skylight-core 2.0.0.beta1

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 (86) hide show
  1. checksums.yaml +7 -0
  2. data/lib/skylight/core/config.rb +454 -0
  3. data/lib/skylight/core/errors.rb +6 -0
  4. data/lib/skylight/core/fanout.rb +44 -0
  5. data/lib/skylight/core/formatters/http.rb +23 -0
  6. data/lib/skylight/core/gc.rb +107 -0
  7. data/lib/skylight/core/instrumentable.rb +144 -0
  8. data/lib/skylight/core/instrumenter.rb +249 -0
  9. data/lib/skylight/core/middleware.rb +101 -0
  10. data/lib/skylight/core/normalizers/action_controller/process_action.rb +50 -0
  11. data/lib/skylight/core/normalizers/action_controller/send_file.rb +50 -0
  12. data/lib/skylight/core/normalizers/action_view/render_collection.rb +22 -0
  13. data/lib/skylight/core/normalizers/action_view/render_partial.rb +21 -0
  14. data/lib/skylight/core/normalizers/action_view/render_template.rb +21 -0
  15. data/lib/skylight/core/normalizers/active_job/enqueue_at.rb +21 -0
  16. data/lib/skylight/core/normalizers/active_model_serializers/render.rb +26 -0
  17. data/lib/skylight/core/normalizers/active_record/instantiation.rb +17 -0
  18. data/lib/skylight/core/normalizers/active_record/sql.rb +33 -0
  19. data/lib/skylight/core/normalizers/active_support/cache.rb +20 -0
  20. data/lib/skylight/core/normalizers/active_support/cache_clear.rb +16 -0
  21. data/lib/skylight/core/normalizers/active_support/cache_decrement.rb +16 -0
  22. data/lib/skylight/core/normalizers/active_support/cache_delete.rb +16 -0
  23. data/lib/skylight/core/normalizers/active_support/cache_exist.rb +16 -0
  24. data/lib/skylight/core/normalizers/active_support/cache_fetch_hit.rb +16 -0
  25. data/lib/skylight/core/normalizers/active_support/cache_generate.rb +16 -0
  26. data/lib/skylight/core/normalizers/active_support/cache_increment.rb +16 -0
  27. data/lib/skylight/core/normalizers/active_support/cache_read.rb +16 -0
  28. data/lib/skylight/core/normalizers/active_support/cache_read_multi.rb +16 -0
  29. data/lib/skylight/core/normalizers/active_support/cache_write.rb +16 -0
  30. data/lib/skylight/core/normalizers/coach/handler_finish.rb +36 -0
  31. data/lib/skylight/core/normalizers/coach/middleware_finish.rb +23 -0
  32. data/lib/skylight/core/normalizers/couch_potato/query.rb +20 -0
  33. data/lib/skylight/core/normalizers/data_mapper/sql.rb +12 -0
  34. data/lib/skylight/core/normalizers/default.rb +27 -0
  35. data/lib/skylight/core/normalizers/elasticsearch/request.rb +20 -0
  36. data/lib/skylight/core/normalizers/faraday/request.rb +37 -0
  37. data/lib/skylight/core/normalizers/grape/endpoint.rb +30 -0
  38. data/lib/skylight/core/normalizers/grape/endpoint_render.rb +26 -0
  39. data/lib/skylight/core/normalizers/grape/endpoint_run.rb +33 -0
  40. data/lib/skylight/core/normalizers/grape/endpoint_run_filters.rb +23 -0
  41. data/lib/skylight/core/normalizers/moped/query.rb +100 -0
  42. data/lib/skylight/core/normalizers/sequel/sql.rb +12 -0
  43. data/lib/skylight/core/normalizers/sql.rb +49 -0
  44. data/lib/skylight/core/normalizers.rb +170 -0
  45. data/lib/skylight/core/probes/action_controller.rb +31 -0
  46. data/lib/skylight/core/probes/action_view.rb +37 -0
  47. data/lib/skylight/core/probes/active_model_serializers.rb +55 -0
  48. data/lib/skylight/core/probes/elasticsearch.rb +37 -0
  49. data/lib/skylight/core/probes/excon/middleware.rb +72 -0
  50. data/lib/skylight/core/probes/excon.rb +26 -0
  51. data/lib/skylight/core/probes/faraday.rb +22 -0
  52. data/lib/skylight/core/probes/grape.rb +80 -0
  53. data/lib/skylight/core/probes/httpclient.rb +46 -0
  54. data/lib/skylight/core/probes/middleware.rb +58 -0
  55. data/lib/skylight/core/probes/mongo.rb +171 -0
  56. data/lib/skylight/core/probes/mongoid.rb +21 -0
  57. data/lib/skylight/core/probes/moped.rb +39 -0
  58. data/lib/skylight/core/probes/net_http.rb +64 -0
  59. data/lib/skylight/core/probes/redis.rb +71 -0
  60. data/lib/skylight/core/probes/sequel.rb +33 -0
  61. data/lib/skylight/core/probes/sinatra.rb +69 -0
  62. data/lib/skylight/core/probes/tilt.rb +27 -0
  63. data/lib/skylight/core/probes.rb +129 -0
  64. data/lib/skylight/core/railtie.rb +166 -0
  65. data/lib/skylight/core/subscriber.rb +124 -0
  66. data/lib/skylight/core/test.rb +98 -0
  67. data/lib/skylight/core/trace.rb +190 -0
  68. data/lib/skylight/core/user_config.rb +61 -0
  69. data/lib/skylight/core/util/allocation_free.rb +26 -0
  70. data/lib/skylight/core/util/clock.rb +56 -0
  71. data/lib/skylight/core/util/deploy.rb +132 -0
  72. data/lib/skylight/core/util/gzip.rb +21 -0
  73. data/lib/skylight/core/util/inflector.rb +112 -0
  74. data/lib/skylight/core/util/logging.rb +127 -0
  75. data/lib/skylight/core/util/platform.rb +77 -0
  76. data/lib/skylight/core/util/proxy.rb +13 -0
  77. data/lib/skylight/core/util.rb +14 -0
  78. data/lib/skylight/core/vendor/active_support/notifications.rb +207 -0
  79. data/lib/skylight/core/vendor/active_support/per_thread_registry.rb +52 -0
  80. data/lib/skylight/core/vendor/thread_safe/non_concurrent_cache_backend.rb +133 -0
  81. data/lib/skylight/core/vendor/thread_safe/synchronized_cache_backend.rb +76 -0
  82. data/lib/skylight/core/vendor/thread_safe.rb +126 -0
  83. data/lib/skylight/core/version.rb +6 -0
  84. data/lib/skylight/core/vm/gc.rb +70 -0
  85. data/lib/skylight/core.rb +99 -0
  86. metadata +254 -0
@@ -0,0 +1,144 @@
1
+ module Skylight
2
+ module Core
3
+ module Instrumentable
4
+
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+
8
+ base.const_set(:LOCK, Mutex.new)
9
+
10
+ base.class_eval do
11
+ at_exit do
12
+ if RUBY_VERSION == '1.9.2'
13
+ # workaround for MRI bug losing exit status in at_exit block
14
+ # http://bugs.ruby-lang.org/issues/5218
15
+ exit_status = $!.status if $!.is_a?(SystemExit)
16
+ stop!
17
+ exit exit_status if exit_status
18
+ else
19
+ stop!
20
+ end
21
+ end
22
+ end
23
+
24
+ Skylight::Core::Fanout.register(base)
25
+ end
26
+
27
+ module ClassMethods
28
+
29
+ def instrumenter_class
30
+ Skylight::Core::Instrumenter
31
+ end
32
+
33
+ def instrumenter
34
+ @instrumenter
35
+ end
36
+
37
+ def correlation_header
38
+ nil
39
+ end
40
+
41
+ # Start instrumenting
42
+ def start!(config=nil)
43
+ return @instrumenter if @instrumenter
44
+
45
+ const_get(:LOCK).synchronize do
46
+ return @instrumenter if @instrumenter
47
+
48
+ config ||= {}
49
+ config = config_class.load(config) unless config.is_a?(config_class)
50
+
51
+ @instrumenter = instrumenter_class.new(config).start!
52
+ end
53
+ rescue => e
54
+ message = sprintf("[SKYLIGHT] [#{VERSION}] Unable to start Instrumenter; msg=%s; class=%s", e.message, e.class)
55
+ if config && config.respond_to?(:logger)
56
+ config.logger.warn message
57
+ else
58
+ warn message
59
+ end
60
+ false
61
+ end
62
+
63
+ # Stop instrumenting
64
+ def stop!
65
+ const_get(:LOCK).synchronize do
66
+ return unless @instrumenter
67
+ # This is only really helpful for getting specs to pass.
68
+ @instrumenter.current_trace = nil
69
+
70
+ @instrumenter.shutdown
71
+ @instrumenter = nil
72
+ end
73
+ end
74
+
75
+ # Check tracing
76
+ def tracing?
77
+ instrumenter && instrumenter.current_trace
78
+ end
79
+
80
+ # Start a trace
81
+ def trace(endpoint=nil, cat=nil, title=nil, meta=nil)
82
+ unless instrumenter
83
+ return yield if block_given?
84
+ return
85
+ end
86
+
87
+ if block_given?
88
+ instrumenter.trace(endpoint, cat || DEFAULT_CATEGORY, title, nil, meta) { yield }
89
+ else
90
+ instrumenter.trace(endpoint, cat || DEFAULT_CATEGORY, title, nil, meta)
91
+ end
92
+ end
93
+
94
+ # Instrument
95
+ def instrument(opts = DEFAULT_OPTIONS, &block)
96
+ unless instrumenter
97
+ return yield if block_given?
98
+ return
99
+ end
100
+
101
+ if Hash === opts
102
+ category = opts[:category] || DEFAULT_CATEGORY
103
+ title = opts[:title]
104
+ desc = opts[:description]
105
+ meta = opts[:meta]
106
+ if opts.key?(:annotations)
107
+ warn "call to #instrument included deprecated annotations"
108
+ end
109
+ else
110
+ category = DEFAULT_CATEGORY
111
+ title = opts.to_s
112
+ desc = nil
113
+ meta = nil
114
+ end
115
+
116
+ instrumenter.instrument(category, title, desc, meta, &block)
117
+ end
118
+
119
+ def span_correlation_header(span)
120
+ return unless instrumenter
121
+ instrumenter.span_correlation_header(span)
122
+ end
123
+
124
+ # End a span
125
+ def done(span, meta=nil)
126
+ return unless instrumenter
127
+ instrumenter.done(span, meta)
128
+ end
129
+
130
+ # Temporarily disable
131
+ def disable
132
+ unless instrumenter
133
+ return yield if block_given?
134
+ return
135
+ end
136
+
137
+ instrumenter.disable { yield }
138
+ end
139
+
140
+ end
141
+
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,249 @@
1
+ require 'thread'
2
+ require 'strscan'
3
+
4
+ module Skylight::Core
5
+ # @api private
6
+ class Instrumenter
7
+ KEY = :__skylight_current_trace
8
+
9
+ TOO_MANY_UNIQUES = "<too many unique descriptions>"
10
+
11
+ include Util::Logging
12
+
13
+ class TraceInfo
14
+ def initialize(key=KEY)
15
+ @key = key
16
+ end
17
+
18
+ def current
19
+ Thread.current[@key]
20
+ end
21
+
22
+ def current=(trace)
23
+ Thread.current[@key] = trace
24
+ end
25
+ end
26
+
27
+ attr_reader :config, :gc, :trace_info
28
+
29
+ def self.trace_class
30
+ Trace
31
+ end
32
+
33
+ def self.native_new
34
+ raise "not implemented"
35
+ end
36
+
37
+ def self.new(config)
38
+ config.validate!
39
+
40
+ inst = native_new(config.to_native_env)
41
+ inst.send(:initialize, config)
42
+ inst
43
+ end
44
+
45
+ def initialize(config)
46
+ @gc = config.gc
47
+ @config = config
48
+ @subscriber = Subscriber.new(config, self)
49
+
50
+ key = "#{KEY}_#{self.class.trace_class.name}".gsub(/\W/, '_')
51
+ @trace_info = @config[:trace_info] || TraceInfo.new(key)
52
+ end
53
+
54
+ def native_start
55
+ raise "not implemented"
56
+ end
57
+
58
+ def native_stop
59
+ raise "not implemented"
60
+ end
61
+
62
+ def native_track_desc
63
+ raise "not implemented"
64
+ end
65
+
66
+ def native_submit_trace
67
+ raise "not implemented"
68
+ end
69
+
70
+ def current_trace
71
+ @trace_info.current
72
+ end
73
+
74
+ def current_trace=(trace)
75
+ @trace_info.current = trace
76
+ end
77
+
78
+ def check_install!
79
+ true
80
+ end
81
+
82
+ def start!
83
+ # We do this here since we can't report these issues via Gem install without stopping install entirely.
84
+ check_install!
85
+
86
+ t { "starting instrumenter" }
87
+
88
+ unless config.validate_with_server
89
+ log_error "invalid config"
90
+ return
91
+ end
92
+
93
+ t { "starting native instrumenter" }
94
+ unless native_start
95
+ warn "failed to start instrumenter"
96
+ return
97
+ end
98
+
99
+ config.gc.enable
100
+ @subscriber.register!
101
+
102
+ self
103
+
104
+ rescue Exception => e
105
+ log_error "failed to start instrumenter; msg=%s; config=%s", e.message, config.inspect
106
+ t { e.backtrace.join("\n") }
107
+ nil
108
+ end
109
+
110
+ def shutdown
111
+ @subscriber.unregister!
112
+ native_stop
113
+ end
114
+
115
+ def trace(endpoint, cat, title=nil, desc=nil, meta=nil)
116
+ # If a trace is already in progress, continue with that one
117
+ if trace = @trace_info.current
118
+ return yield(trace) if block_given?
119
+ return trace
120
+ end
121
+
122
+ begin
123
+ trace = self.class.trace_class.new(self, endpoint, Util::Clock.nanos, cat, title, desc, meta)
124
+ rescue Exception => e
125
+ log_error e.message
126
+ t { e.backtrace.join("\n") }
127
+ return
128
+ end
129
+
130
+ @trace_info.current = trace
131
+ return trace unless block_given?
132
+
133
+ begin
134
+ yield trace
135
+
136
+ ensure
137
+ @trace_info.current = nil
138
+ t { "submitting trace" }
139
+ trace.submit
140
+ end
141
+ end
142
+
143
+ def disable
144
+ @disabled = true
145
+ yield
146
+ ensure
147
+ @disabled = false
148
+ end
149
+
150
+ def disabled?
151
+ @disabled
152
+ end
153
+
154
+ def self.match?(string, regex)
155
+ @scanner ||= StringScanner.new('')
156
+ @scanner.string = string
157
+ @scanner.match?(regex)
158
+ end
159
+
160
+ def match?(string, regex)
161
+ self.class.match?(string, regex)
162
+ end
163
+
164
+ def instrument(cat, title=nil, desc=nil, meta=nil)
165
+ raise ArgumentError, 'cat is required' unless cat
166
+
167
+ unless trace = @trace_info.current
168
+ return yield if block_given?
169
+ return
170
+ end
171
+
172
+ cat = cat.to_s
173
+
174
+ unless match?(cat, Skylight::CATEGORY_REGEX)
175
+ warn "invalid skylight instrumentation category; value=%s", cat
176
+ return yield if block_given?
177
+ return
178
+ end
179
+
180
+ cat = "other.#{cat}" unless match?(cat, Skylight::TIER_REGEX)
181
+
182
+ unless sp = trace.instrument(cat, title, desc, meta)
183
+ return yield if block_given?
184
+ return
185
+ end
186
+
187
+ return sp unless block_given?
188
+
189
+ meta = {}
190
+ begin
191
+ yield sp
192
+ rescue Exception => e
193
+ meta = { exception: [e.class.name, e.message], exception_object: e }
194
+ raise e
195
+ ensure
196
+ trace.done(sp, meta)
197
+ end
198
+ end
199
+
200
+ def span_correlation_header(span)
201
+ return unless trace = @trace_info.current
202
+ trace.span_correlation_header(span)
203
+ end
204
+
205
+ def done(span, meta=nil)
206
+ return unless trace = @trace_info.current
207
+ trace.done(span, meta)
208
+ end
209
+
210
+ def limited_description(description)
211
+ endpoint = @trace_info.current.endpoint
212
+
213
+ if description
214
+ if native_track_desc(endpoint, description)
215
+ description
216
+ else
217
+ TOO_MANY_UNIQUES
218
+ end
219
+ end
220
+ end
221
+
222
+ def process(trace)
223
+ t { fmt "processing trace" }
224
+
225
+ if ignore?(trace)
226
+ t { fmt "ignoring trace" }
227
+ return false
228
+ end
229
+
230
+ begin
231
+ native_submit_trace(trace)
232
+ true
233
+ rescue => e
234
+ warn "failed to submit trace to worker; err=%s", e
235
+ false
236
+ end
237
+ end
238
+
239
+ def ignore?(trace)
240
+ config.ignored_endpoints.include?(trace.endpoint.sub(%r{<sk-segment>.+</sk-segment>}, ''))
241
+ end
242
+
243
+ # Return [title, sql]
244
+ def process_sql(sql)
245
+ [nil, sql]
246
+ end
247
+
248
+ end
249
+ end
@@ -0,0 +1,101 @@
1
+ module Skylight::Core
2
+ # @api private
3
+ class Middleware
4
+
5
+ class BodyProxy
6
+ def initialize(body, &block)
7
+ @body, @block, @closed = body, block, false
8
+ end
9
+
10
+ def respond_to?(*args)
11
+ return false if args.first.to_s =~ /^to_ary$/
12
+ super or @body.respond_to?(*args)
13
+ end
14
+
15
+ def close
16
+ return if @closed
17
+ @closed = true
18
+ begin
19
+ @body.close if @body.respond_to? :close
20
+ ensure
21
+ @block.call
22
+ end
23
+ end
24
+
25
+ def closed?
26
+ @closed
27
+ end
28
+
29
+ # N.B. This method is a special case to address the bug described by
30
+ # https://github.com/rack/rack/issues/434.
31
+ # We are applying this special case for #each only. Future bugs of this
32
+ # class will be handled by requesting users to patch their ruby
33
+ # implementation, to save adding too many methods in this class.
34
+ def each(*args, &block)
35
+ @body.each(*args, &block)
36
+ end
37
+
38
+ def method_missing(*args, &block)
39
+ super if args.first.to_s =~ /^to_ary$/
40
+ @body.__send__(*args, &block)
41
+ end
42
+ end
43
+
44
+ def self.with_after_close(resp, &block)
45
+ # Responses should be finished but in some situations they aren't
46
+ # e.g. https://github.com/ruby-grape/grape/issues/1041
47
+ if resp.respond_to?(:finish)
48
+ resp = resp.finish
49
+ end
50
+
51
+ resp[2] = BodyProxy.new(resp[2], &block)
52
+ resp
53
+ end
54
+
55
+ include Util::Logging
56
+
57
+ # For Util::Logging
58
+ attr_reader :config
59
+
60
+ def initialize(app, opts={})
61
+ @app = app
62
+ @config = opts[:config]
63
+ end
64
+
65
+ def instrumentable
66
+ Skylight
67
+ end
68
+
69
+ # Allow for overwriting
70
+ def endpoint_name(_env)
71
+ "Rack"
72
+ end
73
+
74
+ def endpoint_meta(_env)
75
+ nil
76
+ end
77
+
78
+ def call(env)
79
+ if env["REQUEST_METHOD"] == "HEAD"
80
+ t { "middleware skipping HEAD" }
81
+ @app.call(env)
82
+ else
83
+ begin
84
+ t { "middleware beginning trace" }
85
+ trace = instrumentable.trace(endpoint_name(env), 'app.rack.request', nil, endpoint_meta(env))
86
+ resp = @app.call(env)
87
+
88
+ if trace
89
+ Middleware.with_after_close(resp) { trace.submit }
90
+ else
91
+ resp
92
+ end
93
+ rescue Exception
94
+ t { "middleware exception: #{trace}"}
95
+ trace.submit if trace
96
+ raise
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,50 @@
1
+ module Skylight::Core
2
+ module Normalizers
3
+ module ActionController
4
+ # Normalizer for processing a Rails controller action
5
+ class ProcessAction < Normalizer
6
+ register "process_action.action_controller"
7
+
8
+ CAT = "app.controller.request".freeze
9
+
10
+ # Payload Keys: controller, action, params, format, method, path
11
+ # Additional keys available in `normalize_after`: status, view_runtime
12
+ # Along with ones added by probe: variant
13
+
14
+ # @param trace [Skylight::Messages::Trace::Builder]
15
+ # @param name [String] ignored, only present to match API
16
+ # @param payload [Hash]
17
+ # @option payload [String] :controller Controller name
18
+ # @option payload [String] :action Action name
19
+ # @return [Array]
20
+ def normalize(trace, name, payload)
21
+ trace.endpoint = controller_action(payload)
22
+ [ CAT, trace.endpoint, nil ]
23
+ end
24
+
25
+ def normalize_after(trace, span, name, payload)
26
+ return unless config.enable_segments?
27
+
28
+ # Show 'error' if there's an unhandled exception or if the status is 4xx or 5xx
29
+ if payload[:exception] || payload[:exception_object] || payload[:status].to_s =~ /^[45]/
30
+ segment = "error"
31
+ # We won't have a rendered_format if it's a `head` outside of a `respond_to` block.
32
+ elsif payload[:rendered_format]
33
+ # We only show the variant if we actually have a format
34
+ segment = [payload[:rendered_format], payload[:variant]].compact.flatten.join('+')
35
+ end
36
+
37
+ if segment
38
+ trace.endpoint += "<sk-segment>#{segment}</sk-segment>"
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def controller_action(payload)
45
+ "#{payload[:controller]}##{payload[:action]}"
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,50 @@
1
+ module Skylight::Core
2
+ module Normalizers
3
+ module ActionController
4
+
5
+ # Temporary hacks
6
+ begin
7
+ require "action_dispatch/http/mime_type"
8
+ require "action_dispatch/http/mime_types"
9
+ require "rack/utils"
10
+
11
+ class SendFile < Normalizer
12
+ register "send_file.action_controller"
13
+
14
+ CAT = "app.controller.send_file".freeze
15
+ TITLE = "send file".freeze
16
+
17
+ def normalize(trace, name, payload)
18
+ path = payload[:path]
19
+
20
+ title = TITLE
21
+
22
+ # depending on normalization, we probably want this to eventually
23
+ # include the full path, but we need to make sure we have a good
24
+ # deduping strategy first.
25
+ desc = nil
26
+
27
+ [ CAT, title, desc ]
28
+ end
29
+
30
+ private
31
+
32
+ OCTET_STREAM = "application/octet-stream".freeze
33
+ ATTACHMENT = "attachment".freeze
34
+
35
+ def initialize(*)
36
+ super
37
+
38
+ @mimes = Mime::SET.reduce({}) do |hash, mime|
39
+ hash[mime.symbol] = mime.to_s.dup.freeze
40
+ hash
41
+ end
42
+ end
43
+ end
44
+
45
+ rescue LoadError
46
+ end
47
+
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,22 @@
1
+ module Skylight::Core
2
+ module Normalizers
3
+ module ActionView
4
+ # Normalizer for Rails collection rendering
5
+ class RenderCollection < RenderNormalizer
6
+ register "render_collection.action_view"
7
+
8
+ CAT = "view.render.collection".freeze
9
+
10
+ # @param trace [Skylight::Messages::Trace::Builder] ignored, only present to match API
11
+ # @param name [String] ignored, only present to match API
12
+ # @param payload (see RenderNormalizer#normalize_render)
13
+ # @option payload (see RenderNormalizer#normalize_render)
14
+ # @option payload [Integer] :count
15
+ # @return (see RenderNormalizer#normalize_render)
16
+ def normalize(trace, name, payload)
17
+ normalize_render(CAT, payload)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,21 @@
1
+ module Skylight::Core
2
+ module Normalizers
3
+ module ActionView
4
+ # Normalizer for Rails partial rendering
5
+ class RenderPartial < RenderNormalizer
6
+ register "render_partial.action_view"
7
+
8
+ CAT = "view.render.template".freeze
9
+
10
+ # @param trace [Skylight::Messages::Trace::Builder] ignored, only present to match API
11
+ # @param name [String] ignored, only present to match API
12
+ # @param payload (see RenderNormalizer#normalize_render)
13
+ # @option payload (see RenderNormalizer#normalize_render)
14
+ # @return (see RenderNormalizer#normalize_render)
15
+ def normalize(trace, name, payload)
16
+ normalize_render(CAT, payload)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ module Skylight::Core
2
+ module Normalizers
3
+ module ActionView
4
+ # Normalizer for Rails template rendering
5
+ class RenderTemplate < RenderNormalizer
6
+ register "render_template.action_view"
7
+
8
+ CAT = "view.render.template".freeze
9
+
10
+ # @param trace [Skylight::Messages::Trace::Builder] ignored, only present to match API
11
+ # @param name [String] ignored, only present to match API
12
+ # @param payload (see RenderNormalizer#normalize_render)
13
+ # @option payload (see RenderNormalizer#normalize_render)
14
+ # @return (see RenderNormalizer#normalize_render)
15
+ def normalize(trace, name, payload)
16
+ normalize_render(CAT, payload)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ module Skylight::Core
2
+ module Normalizers
3
+ module ActiveJob
4
+ class EnqueueAt < Normalizer
5
+ register "enqueue_at.active_job"
6
+
7
+ CAT = "other.job.enqueue_at".freeze
8
+
9
+ def normalize(_trace, _name, payload)
10
+ title = "Enqueue #{payload[:job].class}"
11
+
12
+ adapter_class_name = payload[:adapter].class.name
13
+ adapter_name = adapter_class_name.match(/^ActiveJob::QueueAdapters::(\w+)Adapter$/)[1].underscore
14
+ desc = "{ adapter: '#{adapter_name}', queue: '#{payload[:job].queue_name}' }"
15
+
16
+ [ CAT, title, desc ]
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,26 @@
1
+ module Skylight::Core
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
+
9
+ def normalize(trace, name, payload)
10
+ serializer_class = payload[:serializer]
11
+
12
+ title = serializer_class.name.sub(/^ActiveModel::(Serializer::)?/, '')
13
+
14
+ if adapter_instance = payload[:adapter]
15
+ adapter_name = adapter_instance.class.name
16
+ .sub(/^ActiveModel::Serializer::Adapter::/, '')
17
+ .sub(/^ActiveModelSerializers::Adapter::/, '')
18
+ desc = "Adapter: #{adapter_name}"
19
+ end
20
+
21
+ [ CAT, title, desc ]
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end