skylight 5.1.0.beta → 5.1.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +390 -371
  3. data/CLA.md +1 -1
  4. data/LICENSE.md +7 -17
  5. data/README.md +1 -1
  6. data/ext/extconf.rb +42 -54
  7. data/lib/skylight.rb +20 -30
  8. data/lib/skylight/api.rb +22 -18
  9. data/lib/skylight/cli.rb +47 -46
  10. data/lib/skylight/cli/doctor.rb +50 -50
  11. data/lib/skylight/cli/helpers.rb +19 -19
  12. data/lib/skylight/cli/merger.rb +141 -139
  13. data/lib/skylight/config.rb +265 -302
  14. data/lib/skylight/deprecation.rb +4 -4
  15. data/lib/skylight/errors.rb +3 -4
  16. data/lib/skylight/extensions.rb +17 -29
  17. data/lib/skylight/extensions/source_location.rb +128 -128
  18. data/lib/skylight/formatters/http.rb +1 -3
  19. data/lib/skylight/gc.rb +30 -40
  20. data/lib/skylight/helpers.rb +43 -41
  21. data/lib/skylight/instrumenter.rb +25 -18
  22. data/lib/skylight/middleware.rb +31 -35
  23. data/lib/skylight/native.rb +8 -10
  24. data/lib/skylight/native_ext_fetcher.rb +10 -12
  25. data/lib/skylight/normalizers.rb +43 -39
  26. data/lib/skylight/normalizers/action_controller/process_action.rb +24 -25
  27. data/lib/skylight/normalizers/action_controller/send_file.rb +7 -6
  28. data/lib/skylight/normalizers/action_dispatch/route_set.rb +7 -7
  29. data/lib/skylight/normalizers/active_job/perform.rb +48 -44
  30. data/lib/skylight/normalizers/active_model_serializers/render.rb +7 -3
  31. data/lib/skylight/normalizers/active_storage.rb +11 -13
  32. data/lib/skylight/normalizers/active_support/cache.rb +1 -12
  33. data/lib/skylight/normalizers/coach/handler_finish.rb +1 -3
  34. data/lib/skylight/normalizers/default.rb +1 -9
  35. data/lib/skylight/normalizers/faraday/request.rb +1 -3
  36. data/lib/skylight/normalizers/grape/endpoint.rb +13 -19
  37. data/lib/skylight/normalizers/grape/endpoint_run.rb +16 -18
  38. data/lib/skylight/normalizers/grape/endpoint_run_filters.rb +1 -3
  39. data/lib/skylight/normalizers/graphql/base.rb +23 -28
  40. data/lib/skylight/normalizers/render.rb +19 -21
  41. data/lib/skylight/normalizers/shrine.rb +15 -17
  42. data/lib/skylight/normalizers/sql.rb +4 -4
  43. data/lib/skylight/probes.rb +38 -46
  44. data/lib/skylight/probes/action_controller.rb +32 -28
  45. data/lib/skylight/probes/action_dispatch/request_id.rb +9 -5
  46. data/lib/skylight/probes/action_dispatch/routing/route_set.rb +7 -5
  47. data/lib/skylight/probes/action_view.rb +9 -10
  48. data/lib/skylight/probes/active_job_enqueue.rb +3 -9
  49. data/lib/skylight/probes/active_model_serializers.rb +8 -8
  50. data/lib/skylight/probes/delayed_job.rb +37 -42
  51. data/lib/skylight/probes/elasticsearch.rb +3 -5
  52. data/lib/skylight/probes/excon.rb +1 -1
  53. data/lib/skylight/probes/excon/middleware.rb +22 -23
  54. data/lib/skylight/probes/graphql.rb +2 -7
  55. data/lib/skylight/probes/middleware.rb +14 -5
  56. data/lib/skylight/probes/mongo.rb +83 -91
  57. data/lib/skylight/probes/net_http.rb +1 -1
  58. data/lib/skylight/probes/redis.rb +5 -17
  59. data/lib/skylight/probes/sequel.rb +7 -11
  60. data/lib/skylight/probes/sinatra.rb +8 -5
  61. data/lib/skylight/probes/tilt.rb +2 -4
  62. data/lib/skylight/railtie.rb +121 -135
  63. data/lib/skylight/sidekiq.rb +4 -5
  64. data/lib/skylight/subscriber.rb +31 -33
  65. data/lib/skylight/test.rb +89 -84
  66. data/lib/skylight/trace.rb +121 -115
  67. data/lib/skylight/user_config.rb +14 -17
  68. data/lib/skylight/util/clock.rb +1 -0
  69. data/lib/skylight/util/component.rb +18 -21
  70. data/lib/skylight/util/deploy.rb +11 -13
  71. data/lib/skylight/util/http.rb +104 -105
  72. data/lib/skylight/util/logging.rb +4 -6
  73. data/lib/skylight/util/lru_cache.rb +2 -6
  74. data/lib/skylight/util/platform.rb +2 -6
  75. data/lib/skylight/util/ssl.rb +1 -3
  76. data/lib/skylight/version.rb +1 -1
  77. data/lib/skylight/vm/gc.rb +1 -9
  78. metadata +4 -4
@@ -15,7 +15,7 @@ module Skylight
15
15
  # If we're connected with a persistent socket
16
16
  host ||= address
17
17
 
18
- path = req.path
18
+ path = req.path
19
19
  scheme = use_ssl? ? "https" : "http"
20
20
 
21
21
  # Contained in the path
@@ -4,17 +4,9 @@ module Skylight
4
4
  # Unfortunately, because of the nature of pipelining, there's no way for us to
5
5
  # give a time breakdown on the individual items.
6
6
 
7
- PIPELINED_OPTS = {
8
- category: "db.redis.pipelined".freeze,
9
- title: "PIPELINE".freeze,
10
- internal: true
11
- }.freeze
12
-
13
- MULTI_OPTS = {
14
- category: "db.redis.multi".freeze,
15
- title: "MULTI".freeze,
16
- internal: true
17
- }.freeze
7
+ PIPELINED_OPTS = { category: "db.redis.pipelined".freeze, title: "PIPELINE".freeze, internal: true }.freeze
8
+
9
+ MULTI_OPTS = { category: "db.redis.multi".freeze, title: "MULTI".freeze, internal: true }.freeze
18
10
 
19
11
  module ClientInstrumentation
20
12
  def call(command, *)
@@ -22,11 +14,7 @@ module Skylight
22
14
 
23
15
  return super if command_name == :auth
24
16
 
25
- opts = {
26
- category: "db.redis.command",
27
- title: command_name.upcase.to_s,
28
- internal: true
29
- }
17
+ opts = { category: "db.redis.command", title: command_name.upcase.to_s, internal: true }
30
18
 
31
19
  Skylight.instrument(opts) { super }
32
20
  end
@@ -48,7 +36,7 @@ module Skylight
48
36
 
49
37
  if !version || version < Gem::Version.new("3.0.0")
50
38
  Skylight.error "The installed version of Redis doesn't support Middlewares. " \
51
- "At least version 3.0.0 is required."
39
+ "At least version 3.0.0 is required."
52
40
  return
53
41
  end
54
42
 
@@ -8,20 +8,16 @@ module Skylight
8
8
 
9
9
  method_name = ::Sequel::Database.method_defined?(:log_connection_yield) ? "log_connection_yield" : "log_yield"
10
10
 
11
- mod = Module.new do
12
- define_method method_name do |sql, *args, &block|
13
- super(sql, *args) do
14
- ::ActiveSupport::Notifications.instrument(
15
- "sql.sequel",
16
- sql: sql,
17
- name: "SQL",
18
- binds: args
19
- ) do
20
- block.call
11
+ mod =
12
+ Module.new do
13
+ define_method method_name do |sql, *args, &block|
14
+ super(sql, *args) do
15
+ ::ActiveSupport::Notifications.instrument("sql.sequel", sql: sql, name: "SQL", binds: args) do
16
+ block.call
17
+ end
21
18
  end
22
19
  end
23
20
  end
24
- end
25
21
 
26
22
  ::Sequel::Database.prepend(mod)
27
23
  end
@@ -37,11 +37,14 @@ module Skylight
37
37
  end
38
38
 
39
39
  def compile_template(engine, data, options, *)
40
- # Pass along a useful "virtual path" to Tilt. The Tilt probe will handle
41
- # instrumenting correctly.
42
- options[:sky_virtual_path] = data.is_a?(Symbol) ? data.to_s : "Inline template (#{engine})"
43
-
44
- super
40
+ super.tap do |template|
41
+ if defined?(::Tilt::Template) && template.is_a?(::Tilt::Template)
42
+ # Pass along a useful "virtual path" to Tilt. The Tilt probe will handle
43
+ # instrumenting correctly.
44
+ virtual_path = data.is_a?(Symbol) ? data.to_s : "Inline template (#{engine})"
45
+ template.instance_variable_set(:@__sky_virtual_path, virtual_path)
46
+ end
47
+ end
45
48
  end
46
49
  end
47
50
 
@@ -6,12 +6,10 @@ module Skylight
6
6
  def render(*args, &block)
7
7
  opts = {
8
8
  category: "view.render.template",
9
- title: options[:sky_virtual_path] || basename || "Unknown template name"
9
+ title: @__sky_virtual_path || options[:sky_virtual_path] || basename || "Unknown template name"
10
10
  }
11
11
 
12
- Skylight.instrument(opts) do
13
- super(*args, &block)
14
- end
12
+ Skylight.instrument(opts) { super(*args, &block) }
15
13
  end
16
14
  end
17
15
 
@@ -28,183 +28,169 @@ module Skylight
28
28
 
29
29
  private
30
30
 
31
- # We must have an opt-in signal
32
- def show_worker_activation_warning(sk_config)
33
- reasons = []
34
- reasons << "the 'active_job' probe is enabled" if sk_rails_config.probes.include?("active_job")
35
- reasons << "the 'delayed_job' probe is enabled" if sk_rails_config.probes.include?("delayed_job")
36
- reasons << "SKYLIGHT_ENABLE_SIDEKIQ is set" if sk_config.enable_sidekiq?
31
+ # We must have an opt-in signal
32
+ def show_worker_activation_warning(sk_config)
33
+ reasons = []
34
+ reasons << "the 'active_job' probe is enabled" if sk_rails_config.probes.include?("active_job")
35
+ reasons << "the 'delayed_job' probe is enabled" if sk_rails_config.probes.include?("delayed_job")
36
+ reasons << "SKYLIGHT_ENABLE_SIDEKIQ is set" if sk_config.enable_sidekiq?
37
37
 
38
- return if reasons.empty?
38
+ return if reasons.empty?
39
39
 
40
- sk_config.logger.warn("Activating Skylight for Background Jobs because #{reasons.to_sentence}")
41
- end
40
+ sk_config.logger.warn("Activating Skylight for Background Jobs because #{reasons.to_sentence}")
41
+ end
42
42
 
43
- def log_prefix
44
- "[SKYLIGHT] [#{Skylight::VERSION}]"
45
- end
43
+ def log_prefix
44
+ "[SKYLIGHT] [#{Skylight::VERSION}]"
45
+ end
46
46
 
47
- def development_warning
48
- "#{log_prefix} Running Skylight in development mode. No data will be reported until you deploy your app.\n" \
49
- "(To disable this message for all local apps, run `skylight disable_dev_warning`.)"
50
- end
47
+ def development_warning
48
+ "#{log_prefix} Running Skylight in development mode. No data will be reported until you deploy your app.\n" \
49
+ "(To disable this message for all local apps, run `skylight disable_dev_warning`.)"
50
+ end
51
51
 
52
- def run_initializer(app)
53
- # Load probes even when agent is inactive to catch probe related bugs sooner
54
- load_probes
52
+ def run_initializer(app)
53
+ # Load probes even when agent is inactive to catch probe related bugs sooner
54
+ load_probes
55
55
 
56
- config = load_skylight_config(app)
56
+ config = load_skylight_config(app)
57
57
 
58
- if activate?(config)
59
- if config
60
- if Skylight.start!(config)
61
- set_middleware_position(app, config)
62
- Rails.logger.info "#{log_prefix} Skylight agent enabled"
63
- else
64
- Rails.logger.info "#{log_prefix} Unable to start, see the Skylight logs for more details"
65
- end
66
- end
67
- elsif Rails.env.development?
68
- unless config.user_config.disable_dev_warning?
69
- log_warning config, development_warning
70
- end
71
- elsif !Rails.env.test?
72
- unless config.user_config.disable_env_warning?
73
- log_warning config, "#{log_prefix} You are running in the #{Rails.env} environment but haven't added it " \
74
- "to config.skylight.environments, so no data will be sent to Skylight servers."
58
+ if activate?(config)
59
+ if config
60
+ if Skylight.start!(config)
61
+ set_middleware_position(app, config)
62
+ Rails.logger.info "#{log_prefix} Skylight agent enabled"
63
+ else
64
+ Rails.logger.info "#{log_prefix} Unable to start, see the Skylight logs for more details"
75
65
  end
76
66
  end
77
- rescue Skylight::ConfigError => e
78
- Rails.logger.error "#{log_prefix} #{e.message}; disabling Skylight agent"
79
- end
80
-
81
- def log_warning(config, msg)
82
- if config
83
- config.alert_logger.warn(msg)
84
- else
85
- Rails.logger.warn(msg)
67
+ elsif Rails.env.development?
68
+ log_warning config, development_warning unless config.user_config.disable_dev_warning?
69
+ elsif !Rails.env.test?
70
+ unless config.user_config.disable_env_warning?
71
+ log_warning config,
72
+ "#{log_prefix} You are running in the #{Rails.env} environment but haven't added it " \
73
+ "to config.skylight.environments, so no data will be sent to Skylight servers."
86
74
  end
87
75
  end
76
+ rescue Skylight::ConfigError => e
77
+ Rails.logger.error "#{log_prefix} #{e.message}; disabling Skylight agent"
78
+ end
88
79
 
89
- def existent_paths(paths)
90
- paths.respond_to?(:existent) ? paths.existent : paths.select { |f| File.exist?(f) }
91
- end
80
+ def log_warning(config, msg)
81
+ config ? config.alert_logger.warn(msg) : Rails.logger.warn(msg)
82
+ end
92
83
 
93
- def load_skylight_config(app)
94
- path = config_path(app)
95
- path = nil unless File.exist?(path)
84
+ def existent_paths(paths)
85
+ paths.respond_to?(:existent) ? paths.existent : paths.select { |f| File.exist?(f) }
86
+ end
96
87
 
97
- unless (tmp = app.config.paths["tmp"].first)
98
- Rails.logger.error "#{log_prefix} tmp directory missing from rails configuration"
99
- return nil
100
- end
88
+ def load_skylight_config(app)
89
+ path = config_path(app)
90
+ path = nil unless File.exist?(path)
101
91
 
102
- config = Config.load(file: path, priority_key: Rails.env.to_s)
103
- config[:root] = Rails.root
92
+ unless (tmp = app.config.paths["tmp"].first)
93
+ Rails.logger.error "#{log_prefix} tmp directory missing from rails configuration"
94
+ return nil
95
+ end
104
96
 
105
- configure_logging(config, app)
97
+ config = Config.load(file: path, priority_key: Rails.env.to_s)
98
+ config[:root] = Rails.root
106
99
 
107
- config[:'daemon.sockdir_path'] ||= tmp
108
- config[:'normalizers.render.view_paths'] = existent_paths(app.config.paths["app/views"]) + [Rails.root.to_s]
100
+ configure_logging(config, app)
109
101
 
110
- if config[:report_rails_env]
111
- config[:env] ||= Rails.env.to_s
112
- end
102
+ config[:'daemon.sockdir_path'] ||= tmp
103
+ config[:'normalizers.render.view_paths'] = existent_paths(app.config.paths["app/views"]) + [Rails.root.to_s]
113
104
 
114
- config
115
- end
105
+ config[:env] ||= Rails.env.to_s if config[:report_rails_env]
116
106
 
117
- def configure_logging(config, app)
118
- if (logger = sk_rails_config(app).logger)
119
- config.logger = logger
120
- else
121
- # Configure the log file destination
122
- if (log_file = sk_rails_config(app).log_file)
123
- config["log_file"] = log_file
124
- end
107
+ config
108
+ end
125
109
 
126
- if (native_log_file = sk_rails_config(app).native_log_file)
127
- config["native_log_file"] = native_log_file
128
- end
110
+ def configure_logging(config, app)
111
+ if (logger = sk_rails_config(app).logger)
112
+ config.logger = logger
113
+ else
114
+ # Configure the log file destination
115
+ if (log_file = sk_rails_config(app).log_file)
116
+ config["log_file"] = log_file
117
+ end
129
118
 
130
- if !config.key?("log_file") && !config.on_heroku?
131
- config["log_file"] = File.join(Rails.root, "log/skylight.log")
132
- end
119
+ if (native_log_file = sk_rails_config(app).native_log_file)
120
+ config["native_log_file"] = native_log_file
121
+ end
133
122
 
134
- # Configure the log level
135
- if (level = sk_rails_config(app).log_level)
123
+ config["log_file"] = File.join(Rails.root, "log/skylight.log") if !config.key?("log_file") && !config.on_heroku?
124
+
125
+ # Configure the log level
126
+ if (level = sk_rails_config(app).log_level)
127
+ config["log_level"] = level
128
+ elsif !config.key?("log_level")
129
+ if (level = app.config.log_level)
136
130
  config["log_level"] = level
137
- elsif !config.key?("log_level")
138
- if (level = app.config.log_level)
139
- config["log_level"] = level
140
- end
141
131
  end
142
132
  end
143
133
  end
134
+ end
144
135
 
145
- def config_path(app)
146
- File.expand_path(sk_rails_config.config_path, app.root)
147
- end
136
+ def config_path(app)
137
+ File.expand_path(sk_rails_config.config_path, app.root)
138
+ end
148
139
 
149
- def environments
150
- Array(sk_rails_config.environments).map { |e| e&.to_s }.compact
151
- end
140
+ def environments
141
+ Array(sk_rails_config.environments).map { |e| e&.to_s }.compact
142
+ end
152
143
 
153
- def activate?(sk_config)
154
- return false unless sk_config
144
+ def activate?(sk_config)
145
+ return false unless sk_config
155
146
 
156
- key = "SKYLIGHT_ENABLED"
157
- activate =
158
- if ENV.key?(key)
159
- ENV[key] !~ /^false$/i
160
- else
161
- environments.include?(Rails.env.to_s)
162
- end
147
+ key = "SKYLIGHT_ENABLED"
148
+ activate = ENV.key?(key) ? ENV[key] !~ /^false$/i : environments.include?(Rails.env.to_s)
163
149
 
164
- show_worker_activation_warning(sk_config) if activate
150
+ show_worker_activation_warning(sk_config) if activate
165
151
 
166
- activate
167
- end
152
+ activate
153
+ end
168
154
 
169
- def load_probes
170
- probes = sk_rails_config.probes || []
171
- Skylight::Probes.probe(*probes)
172
- end
155
+ def load_probes
156
+ probes = sk_rails_config.probes || []
157
+ Skylight::Probes.probe(*probes)
158
+ end
173
159
 
174
- def middleware_position
175
- if sk_rails_config.middleware_position.is_a?(Hash)
176
- sk_rails_config.middleware_position.symbolize_keys
177
- else
178
- sk_rails_config.middleware_position
179
- end
160
+ def middleware_position
161
+ if sk_rails_config.middleware_position.is_a?(Hash)
162
+ sk_rails_config.middleware_position.symbolize_keys
163
+ else
164
+ sk_rails_config.middleware_position
180
165
  end
166
+ end
181
167
 
182
- def insert_middleware(app, config)
183
- if middleware_position.key?(:after)
184
- app.middleware.insert_after(middleware_position[:after], Skylight::Middleware, config: config)
185
- elsif middleware_position.key?(:before)
186
- app.middleware.insert_before(middleware_position[:before], Skylight::Middleware, config: config)
187
- else
188
- raise "The middleware position you have set is invalid. Please be sure " \
168
+ def insert_middleware(app, config)
169
+ if middleware_position.key?(:after)
170
+ app.middleware.insert_after(middleware_position[:after], Skylight::Middleware, config: config)
171
+ elsif middleware_position.key?(:before)
172
+ app.middleware.insert_before(middleware_position[:before], Skylight::Middleware, config: config)
173
+ else
174
+ raise "The middleware position you have set is invalid. Please be sure " \
189
175
  "`config.skylight.middleware_position` is set up correctly."
190
- end
191
176
  end
177
+ end
192
178
 
193
- def set_middleware_position(app, config)
194
- if middleware_position.is_a?(Integer)
195
- app.middleware.insert middleware_position, Skylight::Middleware, config: config
196
- elsif middleware_position.is_a?(Hash) && middleware_position.keys.count == 1
197
- insert_middleware(app, config)
198
- elsif middleware_position.nil?
199
- app.middleware.insert 0, Skylight::Middleware, config: config
200
- else
201
- raise "The middleware position you have set is invalid. Please be sure " \
179
+ def set_middleware_position(app, config)
180
+ if middleware_position.is_a?(Integer)
181
+ app.middleware.insert middleware_position, Skylight::Middleware, config: config
182
+ elsif middleware_position.is_a?(Hash) && middleware_position.keys.count == 1
183
+ insert_middleware(app, config)
184
+ elsif middleware_position.nil?
185
+ app.middleware.insert 0, Skylight::Middleware, config: config
186
+ else
187
+ raise "The middleware position you have set is invalid. Please be sure " \
202
188
  "`config.skylight.middleware_position` is set up correctly."
203
- end
204
189
  end
190
+ end
205
191
 
206
- def sk_rails_config(target = self)
207
- target.config.skylight
208
- end
192
+ def sk_rails_config(target = self)
193
+ target.config.skylight
194
+ end
209
195
  end
210
196
  end
@@ -38,11 +38,10 @@ module Skylight
38
38
  end
39
39
  end
40
40
 
41
- ActiveSupport::Notifications.subscribe("started_instrumenter.skylight") \
42
- do |_name, _started, _finished, _unique_id, payload|
43
- if payload[:instrumenter].config.enable_sidekiq?
44
- add_middleware
45
- end
41
+ ActiveSupport::Notifications.subscribe(
42
+ "started_instrumenter.skylight"
43
+ ) do |_name, _started, _finished, _unique_id, payload|
44
+ add_middleware if payload[:instrumenter].config.enable_sidekiq?
46
45
  end
47
46
  end
48
47
  end
@@ -6,17 +6,15 @@ module Skylight
6
6
  attr_reader :config, :normalizers
7
7
 
8
8
  def initialize(config, instrumenter)
9
- @config = config
10
- @normalizers = Normalizers.build(config)
9
+ @config = config
10
+ @normalizers = Normalizers.build(config)
11
11
  @instrumenter = instrumenter
12
- @subscribers = []
12
+ @subscribers = []
13
13
  end
14
14
 
15
15
  def register!
16
16
  unregister!
17
- @normalizers.keys.each do |key| # rubocop:disable Style/HashEachMethods
18
- @subscribers << ActiveSupport::Notifications.subscribe(key, self)
19
- end
17
+ @normalizers.each_key { |key| @subscribers << ActiveSupport::Notifications.subscribe(key, self) }
20
18
  end
21
19
 
22
20
  def unregister!
@@ -74,37 +72,37 @@ module Skylight
74
72
 
75
73
  private
76
74
 
77
- def normalize(*args)
78
- @normalizers.normalize(*args)
79
- end
80
-
81
- def normalize_after(*args)
82
- @normalizers.normalize_after(*args)
83
- end
75
+ def normalize(*args)
76
+ @normalizers.normalize(*args)
77
+ end
84
78
 
85
- def _start(trace, name, payload)
86
- result = normalize(trace, name, payload)
79
+ def normalize_after(*args)
80
+ @normalizers.normalize_after(*args)
81
+ end
87
82
 
88
- unless result == :skip
89
- case result.size
90
- when 3, 4
91
- cat, title, desc, meta = result
92
- else
93
- raise "Invalid normalizer result: #{result.inspect}"
94
- end
83
+ def _start(trace, name, payload)
84
+ result = normalize(trace, name, payload)
95
85
 
96
- span = trace.instrument(cat, title, desc, meta)
86
+ unless result == :skip
87
+ case result.size
88
+ when 3, 4
89
+ cat, title, desc, meta = result
90
+ else
91
+ raise "Invalid normalizer result: #{result.inspect}"
97
92
  end
98
- rescue Exception => e
99
- error "Subscriber#start error; msg=%s", e.message
100
- debug "trace=%s", trace.inspect
101
- debug "in: name=%s", name.inspect
102
- debug "in: payload=%s", payload.inspect
103
- debug "out: cat=%s, title=%s, desc=%s", cat.inspect, name.inspect, desc.inspect
104
- t { e.backtrace.join("\n") }
105
- nil
106
- ensure
107
- trace.notifications << Notification.new(name, span)
93
+
94
+ span = trace.instrument(cat, title, desc, meta)
108
95
  end
96
+ rescue Exception => e
97
+ error "Subscriber#start error; msg=%s", e.message
98
+ debug "trace=%s", trace.inspect
99
+ debug "in: name=%s", name.inspect
100
+ debug "in: payload=%s", payload.inspect
101
+ debug "out: cat=%s, title=%s, desc=%s", cat.inspect, name.inspect, desc.inspect
102
+ t { e.backtrace.join("\n") }
103
+ nil
104
+ ensure
105
+ trace.notifications << Notification.new(name, span)
106
+ end
109
107
  end
110
108
  end