skylight 3.1.4 → 5.3.4

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 (126) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +465 -294
  3. data/CLA.md +1 -1
  4. data/CONTRIBUTING.md +11 -3
  5. data/ERRORS.md +3 -0
  6. data/LICENSE.md +8 -18
  7. data/README.md +1 -2
  8. data/bin/skylight +1 -1
  9. data/ext/extconf.rb +118 -122
  10. data/ext/libskylight.yml +8 -6
  11. data/ext/skylight_native.c +56 -100
  12. data/lib/skylight/api.rb +41 -27
  13. data/lib/skylight/cli/doctor.rb +68 -70
  14. data/lib/skylight/cli/helpers.rb +3 -5
  15. data/lib/skylight/cli/merger.rb +99 -92
  16. data/lib/skylight/cli.rb +40 -43
  17. data/lib/skylight/config.rb +656 -201
  18. data/lib/skylight/data/cacert.pem +730 -1023
  19. data/lib/skylight/deprecation.rb +17 -0
  20. data/lib/skylight/errors.rb +34 -16
  21. data/lib/skylight/extensions/source_location.rb +291 -0
  22. data/lib/skylight/extensions.rb +95 -0
  23. data/lib/skylight/formatters/http.rb +18 -0
  24. data/lib/skylight/gc.rb +99 -0
  25. data/lib/skylight/helpers.rb +82 -39
  26. data/lib/skylight/instrumenter.rb +339 -9
  27. data/lib/skylight/middleware.rb +147 -1
  28. data/lib/skylight/native.rb +71 -23
  29. data/lib/skylight/native_ext_fetcher.rb +39 -47
  30. data/lib/skylight/normalizers/action_controller/process_action.rb +68 -0
  31. data/lib/skylight/normalizers/action_controller/send_file.rb +51 -0
  32. data/lib/skylight/normalizers/action_dispatch/process_middleware.rb +22 -0
  33. data/lib/skylight/normalizers/action_dispatch/route_set.rb +27 -0
  34. data/lib/skylight/normalizers/action_view/render_collection.rb +24 -0
  35. data/lib/skylight/normalizers/action_view/render_layout.rb +25 -0
  36. data/lib/skylight/normalizers/action_view/render_partial.rb +23 -0
  37. data/lib/skylight/normalizers/action_view/render_template.rb +23 -0
  38. data/lib/skylight/normalizers/active_job/perform.rb +87 -0
  39. data/lib/skylight/normalizers/active_model_serializers/render.rb +32 -0
  40. data/lib/skylight/normalizers/active_record/instantiation.rb +16 -0
  41. data/lib/skylight/normalizers/active_record/sql.rb +20 -0
  42. data/lib/skylight/normalizers/active_storage.rb +28 -0
  43. data/lib/skylight/normalizers/active_support/cache.rb +11 -0
  44. data/lib/skylight/normalizers/active_support/cache_clear.rb +16 -0
  45. data/lib/skylight/normalizers/active_support/cache_decrement.rb +16 -0
  46. data/lib/skylight/normalizers/active_support/cache_delete.rb +16 -0
  47. data/lib/skylight/normalizers/active_support/cache_exist.rb +16 -0
  48. data/lib/skylight/normalizers/active_support/cache_fetch_hit.rb +16 -0
  49. data/lib/skylight/normalizers/active_support/cache_generate.rb +16 -0
  50. data/lib/skylight/normalizers/active_support/cache_increment.rb +16 -0
  51. data/lib/skylight/normalizers/active_support/cache_read.rb +16 -0
  52. data/lib/skylight/normalizers/active_support/cache_read_multi.rb +16 -0
  53. data/lib/skylight/normalizers/active_support/cache_write.rb +16 -0
  54. data/lib/skylight/normalizers/coach/handler_finish.rb +44 -0
  55. data/lib/skylight/normalizers/coach/middleware_finish.rb +33 -0
  56. data/lib/skylight/normalizers/couch_potato/query.rb +20 -0
  57. data/lib/skylight/normalizers/data_mapper/sql.rb +12 -0
  58. data/lib/skylight/normalizers/default.rb +24 -0
  59. data/lib/skylight/normalizers/elasticsearch/request.rb +20 -0
  60. data/lib/skylight/normalizers/faraday/request.rb +38 -0
  61. data/lib/skylight/normalizers/grape/endpoint.rb +28 -0
  62. data/lib/skylight/normalizers/grape/endpoint_render.rb +25 -0
  63. data/lib/skylight/normalizers/grape/endpoint_run.rb +39 -0
  64. data/lib/skylight/normalizers/grape/endpoint_run_filters.rb +20 -0
  65. data/lib/skylight/normalizers/grape/format_response.rb +20 -0
  66. data/lib/skylight/normalizers/graphiti/render.rb +22 -0
  67. data/lib/skylight/normalizers/graphiti/resolve.rb +31 -0
  68. data/lib/skylight/normalizers/graphql/base.rb +127 -0
  69. data/lib/skylight/normalizers/render.rb +79 -0
  70. data/lib/skylight/normalizers/sequel/sql.rb +12 -0
  71. data/lib/skylight/normalizers/shrine.rb +32 -0
  72. data/lib/skylight/normalizers/sql.rb +41 -0
  73. data/lib/skylight/normalizers.rb +157 -0
  74. data/lib/skylight/probes/action_controller.rb +52 -0
  75. data/lib/skylight/probes/action_dispatch/request_id.rb +33 -0
  76. data/lib/skylight/probes/action_dispatch/routing/route_set.rb +30 -0
  77. data/lib/skylight/probes/action_dispatch.rb +2 -0
  78. data/lib/skylight/probes/action_view.rb +42 -0
  79. data/lib/skylight/probes/active_job.rb +27 -0
  80. data/lib/skylight/probes/active_job_enqueue.rb +35 -0
  81. data/lib/skylight/probes/active_model_serializers.rb +50 -0
  82. data/lib/skylight/probes/active_record_async.rb +96 -0
  83. data/lib/skylight/probes/delayed_job.rb +144 -0
  84. data/lib/skylight/probes/elasticsearch.rb +45 -0
  85. data/lib/skylight/probes/excon/middleware.rb +65 -0
  86. data/lib/skylight/probes/excon.rb +25 -0
  87. data/lib/skylight/probes/faraday.rb +23 -0
  88. data/lib/skylight/probes/graphql.rb +38 -0
  89. data/lib/skylight/probes/httpclient.rb +44 -0
  90. data/lib/skylight/probes/middleware.rb +135 -0
  91. data/lib/skylight/probes/mongo.rb +169 -0
  92. data/lib/skylight/probes/mongoid.rb +6 -0
  93. data/lib/skylight/probes/net_http.rb +54 -0
  94. data/lib/skylight/probes/rack_builder.rb +37 -0
  95. data/lib/skylight/probes/redis.rb +68 -0
  96. data/lib/skylight/probes/sequel.rb +29 -0
  97. data/lib/skylight/probes/sinatra.rb +66 -0
  98. data/lib/skylight/probes/sinatra_add_middleware.rb +10 -10
  99. data/lib/skylight/probes/tilt.rb +25 -0
  100. data/lib/skylight/probes.rb +172 -0
  101. data/lib/skylight/railtie.rb +172 -15
  102. data/lib/skylight/sidekiq.rb +47 -0
  103. data/lib/skylight/sinatra.rb +2 -2
  104. data/lib/skylight/subscriber.rb +130 -0
  105. data/lib/skylight/test.rb +147 -0
  106. data/lib/skylight/trace.rb +331 -15
  107. data/lib/skylight/user_config.rb +60 -0
  108. data/lib/skylight/util/allocation_free.rb +26 -0
  109. data/lib/skylight/util/clock.rb +57 -0
  110. data/lib/skylight/util/component.rb +47 -9
  111. data/lib/skylight/util/deploy.rb +24 -40
  112. data/lib/skylight/util/gzip.rb +20 -0
  113. data/lib/skylight/util/hostname.rb +4 -4
  114. data/lib/skylight/util/http.rb +62 -71
  115. data/lib/skylight/util/instrumenter_method.rb +26 -0
  116. data/lib/skylight/util/logging.rb +136 -0
  117. data/lib/skylight/util/lru_cache.rb +36 -0
  118. data/lib/skylight/util/platform.rb +74 -0
  119. data/lib/skylight/util/proxy.rb +13 -0
  120. data/lib/skylight/util/ssl.rb +4 -28
  121. data/lib/skylight/util.rb +12 -0
  122. data/lib/skylight/vendor/cli/thor/rake_compat.rb +1 -1
  123. data/lib/skylight/version.rb +5 -1
  124. data/lib/skylight/vm/gc.rb +60 -0
  125. data/lib/skylight.rb +213 -24
  126. metadata +171 -53
@@ -0,0 +1,87 @@
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
12
+ .class
13
+ .name
14
+ .to_s
15
+ .tap do |str|
16
+ if str.match(DELIVERY_JOB)
17
+ mailer_class, mailer_method, * = job_instance.arguments
18
+ return "#{mailer_class}##{mailer_method}", str if mailer_class && mailer_method
19
+ end
20
+ end
21
+ end
22
+
23
+ CAT = "app.job.perform".freeze
24
+
25
+ def normalize(trace, _name, payload)
26
+ title = payload[:job].class.to_s
27
+ adapter_name = normalize_adapter_name(payload[:adapter])
28
+ desc = "{ adapter: '#{adapter_name}', queue: '#{payload[:job].queue_name}' }"
29
+
30
+ maybe_set_endpoint(trace, payload)
31
+
32
+ [CAT, title, desc]
33
+ end
34
+
35
+ def normalize_after(trace, _span, _name, payload)
36
+ maybe_set_endpoint(trace, payload)
37
+ end
38
+
39
+ private
40
+
41
+ def process_meta_options(payload)
42
+ # provide hints to override default source_location behavior
43
+ super.merge(source_location_hint: [:instance_method, payload[:job].class.to_s, "perform"])
44
+ end
45
+
46
+ def normalize_adapter_name(adapter)
47
+ adapter_string = adapter.is_a?(Class) ? adapter.to_s : adapter.class.to_s
48
+ adapter_string[/ActiveJob::QueueAdapters::(\w+)Adapter/, 1].underscore
49
+ rescue StandardError
50
+ "active_job"
51
+ end
52
+
53
+ def maybe_set_endpoint(trace, payload)
54
+ endpoint = normalize_title(payload[:job])
55
+
56
+ # Always assign the endpoint if it has not yet been assigned by the ActiveJob probe.
57
+ if !trace.endpoint ||
58
+ (defined?(Skylight::Probes::ActiveJob::TITLE) && trace.endpoint == Skylight::Probes::ActiveJob::TITLE) ||
59
+ (
60
+ defined?(Skylight::Probes::DelayedJob::Probe::UNKNOWN) &&
61
+ trace.endpoint == Skylight::Probes::DelayedJob::Probe::UNKNOWN
62
+ ) ||
63
+ # If a job is called using #perform_now inside a controller action
64
+ # or within another job's #perform method, we do not want this to
65
+ # overwrite the existing endpoint name (unless it is the default from ActiveJob).
66
+ #
67
+ # If the current endpoint name matches this payload, return true to allow the
68
+ # segment to be assigned by normalize_after.
69
+ trace.endpoint =~ DELIVERY_JOB ||
70
+ # This adapter wrapper needs to be handled specifically due to interactions with the
71
+ # standalone Delayed::Job probe, as there is no consistent way to get the wrapped
72
+ # job name among all Delayed::Job backends.
73
+ trace.endpoint == DELAYED_JOB_WRAPPER
74
+ trace.endpoint = endpoint
75
+ end
76
+
77
+ trace.segment = payload[:job].queue_name if trace.endpoint == endpoint && config.enable_segments?
78
+ end
79
+
80
+ def normalize_title(job_instance)
81
+ title, * = self.class.normalize_title(job_instance)
82
+ title
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,32 @@
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 =
18
+ adapter_instance
19
+ .class
20
+ .name
21
+ .to_s
22
+ .sub(/^ActiveModel::Serializer::Adapter::/, "")
23
+ .sub(/^ActiveModelSerializers::Adapter::/, "")
24
+ desc = "Adapter: #{adapter_name}"
25
+ end
26
+
27
+ [CAT, title, desc]
28
+ end
29
+ end
30
+ end
31
+ end
32
+ 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,20 @@
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
+
11
+ class FutureResult < Normalizer
12
+ register "future_result.active_record"
13
+
14
+ def normalize(_trace, _name, payload)
15
+ ["db.future_result", "Async #{payload[:args][1] || "Query"}"]
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,28 @@
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 { |key| register key }
18
+
19
+ def normalize(_trace, name, _payload)
20
+ title = ["ActiveStorage", TITLES[name]].join(" ")
21
+
22
+ cat = "app.#{name.split(".").reverse.join(".")}"
23
+
24
+ [cat, title, nil]
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,11 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module ActiveSupport
4
+ class Cache < Normalizer
5
+ %w[clear decrement delete exist fetch_hit generate increment read read_multi write].each do |type|
6
+ require "skylight/normalizers/active_support/cache_#{type}"
7
+ end
8
+ end
9
+ end
10
+ end
11
+ 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,44 @@
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
+ trace.segment = segments.join("+") if segments.any?
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,33 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module Coach
4
+ class MiddlewareFinish < 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.middleware.finish"
13
+ else
14
+ register "finish_middleware.coach"
15
+ end
16
+
17
+ CAT = "app.coach.middleware".freeze
18
+
19
+ # See information on the events Coach emits here:
20
+ # https://github.com/gocardless/coach#instrumentation
21
+
22
+ # Called whenever a new middleware is executed. We can expect this to happen
23
+ # within a Coach::Handler.
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
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,20 @@
1
+ require "json"
2
+
3
+ module Skylight
4
+ module Normalizers
5
+ module CouchPotato
6
+ class Query < Normalizer
7
+ register "couch_potato.load"
8
+ register "couch_potato.view"
9
+
10
+ CAT = "db.couch_db.query".freeze
11
+
12
+ def normalize(_trace, name, payload)
13
+ description = payload[:name] if payload
14
+ name = name.sub("couch_potato.", "")
15
+ [CAT, name, description]
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,12 @@
1
+ require "skylight/normalizers/sql"
2
+
3
+ module Skylight
4
+ module Normalizers
5
+ module DataMapper
6
+ # Normalizer for SQL requests
7
+ class SQL < Skylight::Normalizers::SQL
8
+ register "sql.data_mapper"
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,24 @@
1
+ module Skylight
2
+ module Normalizers
3
+ # The default normalizer, used if no other is found.
4
+ class Default < Normalizer
5
+ def initialize
6
+ super(nil) # Pass no config and handle it in new method
7
+ end
8
+
9
+ def config
10
+ Skylight.config
11
+ end
12
+
13
+ # @param trace [Skylight::Messages::Trace::Builder] ignored, only present to match API
14
+ # @param name [String]
15
+ # @param payload [Hash]
16
+ # @option payload [String] :title
17
+ # @option payload [String] :description
18
+ # @return [Array, :skip] the normalized array or `:skip` if `name` is not part of a known {Skylight::TIERS tier}
19
+ def normalize(_trace, name, payload)
20
+ name =~ Skylight::TIER_REGEX ? [name, payload[:title], payload[:description]] : :skip
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,20 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module Elasticsearch
4
+ class Request < Normalizer
5
+ register "request.elasticsearch"
6
+
7
+ CAT = "db.elasticsearch.request".freeze
8
+
9
+ def normalize(_trace, _name, payload)
10
+ path = payload[:path].split("/")
11
+ title = [payload[:method], path[0]].compact.join(" ")
12
+ desc = {}
13
+ desc[:type] = path[1] if path[1]
14
+ desc[:id] = "?" if path[2]
15
+ [CAT, title, desc.empty? ? nil : desc.to_json]
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,38 @@
1
+ require "skylight/formatters/http"
2
+
3
+ module Skylight
4
+ module Normalizers
5
+ module Faraday
6
+ class Request < Normalizer
7
+ register "request.faraday"
8
+
9
+ DISABLED_KEY = :__skylight_faraday_disabled
10
+
11
+ def self.disable
12
+ old_value = Thread.current[DISABLED_KEY]
13
+ Thread.current[DISABLED_KEY] = true
14
+ yield
15
+ ensure
16
+ Thread.current[DISABLED_KEY] = old_value
17
+ end
18
+
19
+ def disabled?
20
+ !!Thread.current[DISABLED_KEY]
21
+ end
22
+
23
+ def normalize(_trace, _name, payload)
24
+ uri = payload[:url]
25
+
26
+ return :skip if disabled?
27
+
28
+ opts = Formatters::HTTP.build_opts(payload[:method], uri.scheme, uri.host, uri.port, uri.path, uri.query)
29
+ description = opts[:title]
30
+
31
+ # We use "Faraday" as the title to differentiate it in the UI in
32
+ # case it's wrapping or is wrapped by another HTTP backend
33
+ [opts[:category], "Faraday", description, opts[:meta]]
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,28 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module Grape
4
+ class Endpoint < Normalizer
5
+ %w[run render run_filters].each { |type| require "skylight/normalizers/grape/endpoint_#{type}" }
6
+
7
+ require "skylight/normalizers/grape/format_response"
8
+
9
+ private
10
+
11
+ def get_method(endpoint)
12
+ method = endpoint.options[:method].first
13
+ method = "#{method}..." if endpoint.options[:method].length > 1
14
+ method
15
+ end
16
+
17
+ def get_path(endpoint)
18
+ endpoint.options[:path].join("/")
19
+ end
20
+
21
+ def get_namespace(endpoint)
22
+ # slice off preceding slash for data continuity
23
+ ::Grape::Namespace.joined_space_path(endpoint.namespace_stackable(:namespace)).to_s[1..]
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,25 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module Grape
4
+ class EndpointRender < Endpoint
5
+ register "endpoint_render.grape"
6
+
7
+ CAT = "app.grape.endpoint".freeze
8
+
9
+ def normalize(_trace, _name, payload)
10
+ if (endpoint = payload[:endpoint])
11
+ path = get_path(endpoint)
12
+ namespace = get_namespace(endpoint)
13
+ method = get_method(endpoint)
14
+
15
+ title = [method, namespace, path].join(" ").gsub(/\s+/, " ")
16
+
17
+ [CAT, title, nil]
18
+ else
19
+ :skip
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,39 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module Grape
4
+ class EndpointRun < Endpoint
5
+ register "endpoint_run.grape"
6
+
7
+ def normalize(trace, _name, payload)
8
+ trace.endpoint = get_endpoint_name(payload[:endpoint]) if payload[:endpoint]
9
+
10
+ # We don't necessarily want this to be all instrumented since it's fairly internal.
11
+ # However, it is a good place to get the endpoint name.
12
+ :skip
13
+ end
14
+
15
+ private
16
+
17
+ def get_endpoint_name(endpoint)
18
+ method = get_method(endpoint)
19
+ path = get_path(endpoint)
20
+ namespace = get_namespace(endpoint)
21
+
22
+ if namespace && !namespace.empty?
23
+ path = "/#{path}" if path[0] != "/"
24
+ path = "#{namespace}#{path}"
25
+ end
26
+
27
+ "#{base_app_name(endpoint)} [#{method}] #{path}".strip
28
+ end
29
+
30
+ def base_app_name(endpoint)
31
+ ep = endpoint.options[:for]
32
+ return ep.name if ep.name
33
+
34
+ ep.base.name if ep.respond_to?(:base) && ep.base.respond_to?(:name)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end