scout_apm 2.6.10 → 3.0.0.pre0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (233) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -2
  3. data/.rubocop.yml +3 -11
  4. data/CHANGELOG.markdown +4 -362
  5. data/Gemfile +1 -14
  6. data/README.markdown +7 -52
  7. data/Rakefile +1 -0
  8. data/ext/allocations/allocations.c +1 -7
  9. data/ext/allocations/extconf.rb +0 -1
  10. data/ext/rusage/rusage.c +0 -26
  11. data/ext/stacks/extconf.rb +37 -0
  12. data/ext/stacks/scout_atomics.h +86 -0
  13. data/ext/stacks/stacks.c +811 -0
  14. data/lib/scout_apm/agent/logging.rb +69 -0
  15. data/lib/scout_apm/agent/reporting.rb +126 -0
  16. data/lib/scout_apm/agent.rb +259 -138
  17. data/lib/scout_apm/app_server_load.rb +15 -41
  18. data/lib/scout_apm/attribute_arranger.rb +3 -14
  19. data/lib/scout_apm/background_job_integrations/delayed_job.rb +1 -70
  20. data/lib/scout_apm/background_job_integrations/sidekiq.rb +24 -31
  21. data/lib/scout_apm/background_worker.rb +12 -23
  22. data/lib/scout_apm/capacity.rb +57 -0
  23. data/lib/scout_apm/config.rb +37 -206
  24. data/lib/scout_apm/context.rb +4 -20
  25. data/lib/scout_apm/deploy_integrations/capistrano_2.cap +12 -0
  26. data/lib/scout_apm/deploy_integrations/capistrano_2.rb +83 -0
  27. data/lib/scout_apm/deploy_integrations/capistrano_3.cap +12 -0
  28. data/lib/scout_apm/deploy_integrations/capistrano_3.rb +88 -0
  29. data/lib/scout_apm/environment.rb +28 -42
  30. data/lib/scout_apm/fake_store.rb +0 -12
  31. data/lib/scout_apm/framework_integrations/rails_2.rb +1 -2
  32. data/lib/scout_apm/framework_integrations/rails_3_or_4.rb +6 -17
  33. data/lib/scout_apm/framework_integrations/sinatra.rb +1 -1
  34. data/lib/scout_apm/histogram.rb +3 -12
  35. data/lib/scout_apm/instant/assets/xmlhttp_instrumentation.html +2 -2
  36. data/lib/scout_apm/instant/middleware.rb +54 -202
  37. data/lib/scout_apm/instant_reporting.rb +7 -7
  38. data/lib/scout_apm/instruments/.DS_Store +0 -0
  39. data/lib/scout_apm/instruments/action_controller_rails_2.rb +9 -15
  40. data/lib/scout_apm/instruments/action_controller_rails_3_rails4.rb +76 -124
  41. data/lib/scout_apm/instruments/active_record.rb +29 -324
  42. data/lib/scout_apm/instruments/delayed_job.rb +57 -0
  43. data/lib/scout_apm/instruments/elasticsearch.rb +6 -10
  44. data/lib/scout_apm/instruments/grape.rb +9 -12
  45. data/lib/scout_apm/instruments/http_client.rb +7 -14
  46. data/lib/scout_apm/instruments/influxdb.rb +6 -10
  47. data/lib/scout_apm/instruments/middleware_detailed.rb +11 -15
  48. data/lib/scout_apm/instruments/middleware_summary.rb +5 -11
  49. data/lib/scout_apm/instruments/mongoid.rb +8 -39
  50. data/lib/scout_apm/instruments/moped.rb +6 -11
  51. data/lib/scout_apm/instruments/net_http.rb +9 -27
  52. data/lib/scout_apm/instruments/percentile_sampler.rb +23 -42
  53. data/lib/scout_apm/instruments/process/process_cpu.rb +6 -11
  54. data/lib/scout_apm/instruments/process/process_memory.rb +12 -17
  55. data/lib/scout_apm/instruments/rails_router.rb +6 -12
  56. data/lib/scout_apm/instruments/redis.rb +6 -10
  57. data/lib/scout_apm/instruments/sinatra.rb +4 -5
  58. data/lib/scout_apm/job_record.rb +2 -4
  59. data/lib/scout_apm/layaway.rb +34 -88
  60. data/lib/scout_apm/layaway_file.rb +3 -13
  61. data/lib/scout_apm/layer.rb +60 -25
  62. data/lib/scout_apm/layer_converters/allocation_metric_converter.rb +6 -7
  63. data/lib/scout_apm/layer_converters/converter_base.rb +14 -203
  64. data/lib/scout_apm/layer_converters/depth_first_walker.rb +10 -22
  65. data/lib/scout_apm/layer_converters/error_converter.rb +8 -8
  66. data/lib/scout_apm/layer_converters/job_converter.rb +50 -37
  67. data/lib/scout_apm/layer_converters/metric_converter.rb +19 -18
  68. data/lib/scout_apm/layer_converters/request_queue_time_converter.rb +13 -13
  69. data/lib/scout_apm/layer_converters/slow_job_converter.rb +116 -52
  70. data/lib/scout_apm/layer_converters/slow_request_converter.rb +120 -51
  71. data/lib/scout_apm/metric_meta.rb +5 -0
  72. data/lib/scout_apm/metric_set.rb +1 -9
  73. data/lib/scout_apm/metric_stats.rb +8 -7
  74. data/lib/scout_apm/middleware.rb +9 -7
  75. data/lib/scout_apm/reporter.rb +24 -71
  76. data/lib/scout_apm/request_histograms.rb +0 -12
  77. data/lib/scout_apm/request_manager.rb +7 -5
  78. data/lib/scout_apm/scored_item_set.rb +0 -7
  79. data/lib/scout_apm/serializers/app_server_load_serializer.rb +0 -4
  80. data/lib/scout_apm/serializers/deploy_serializer.rb +16 -0
  81. data/lib/scout_apm/serializers/directive_serializer.rb +0 -4
  82. data/lib/scout_apm/serializers/payload_serializer.rb +4 -11
  83. data/lib/scout_apm/serializers/payload_serializer_to_json.rb +16 -35
  84. data/lib/scout_apm/serializers/slow_jobs_serializer_to_json.rb +1 -2
  85. data/lib/scout_apm/server_integrations/passenger.rb +1 -1
  86. data/lib/scout_apm/server_integrations/puma.rb +2 -5
  87. data/lib/scout_apm/slow_job_policy.rb +13 -25
  88. data/lib/scout_apm/slow_job_record.rb +4 -13
  89. data/lib/scout_apm/slow_request_policy.rb +13 -25
  90. data/lib/scout_apm/slow_transaction.rb +5 -25
  91. data/lib/scout_apm/store.rb +32 -99
  92. data/lib/scout_apm/trace_compactor.rb +312 -0
  93. data/lib/scout_apm/tracer.rb +31 -35
  94. data/lib/scout_apm/tracked_request.rb +95 -262
  95. data/lib/scout_apm/utils/active_record_metric_name.rb +13 -88
  96. data/lib/scout_apm/utils/backtrace_parser.rb +4 -7
  97. data/lib/scout_apm/utils/fake_stacks.rb +87 -0
  98. data/lib/scout_apm/utils/installed_gems.rb +3 -7
  99. data/lib/scout_apm/utils/klass_helper.rb +2 -8
  100. data/lib/scout_apm/utils/null_logger.rb +13 -0
  101. data/lib/scout_apm/utils/sql_sanitizer.rb +5 -16
  102. data/lib/scout_apm/utils/sql_sanitizer_regex.rb +0 -7
  103. data/lib/scout_apm/utils/sql_sanitizer_regex_1_8_7.rb +0 -6
  104. data/lib/scout_apm/utils/unique_id.rb +0 -27
  105. data/lib/scout_apm/version.rb +2 -1
  106. data/lib/scout_apm.rb +25 -84
  107. data/scout_apm.gemspec +3 -17
  108. data/test/test_helper.rb +3 -57
  109. data/test/unit/agent_test.rb +54 -1
  110. data/test/unit/background_job_integrations/sidekiq_test.rb +3 -0
  111. data/test/unit/config_test.rb +12 -25
  112. data/test/unit/context_test.rb +4 -4
  113. data/test/unit/histogram_test.rb +4 -25
  114. data/test/unit/ignored_uris_test.rb +1 -1
  115. data/test/unit/instruments/active_record_instruments_test.rb +5 -0
  116. data/test/unit/layaway_test.rb +2 -62
  117. data/test/unit/serializers/payload_serializer_test.rb +15 -43
  118. data/test/unit/slow_request_policy_test.rb +6 -15
  119. data/test/unit/sql_sanitizer_test.rb +6 -53
  120. data/test/unit/store_test.rb +4 -73
  121. data/test/unit/utils/active_record_metric_name_test.rb +5 -59
  122. data/test/unit/utils/backtrace_parser_test.rb +1 -6
  123. data/tester.rb +53 -0
  124. metadata +28 -229
  125. data/.travis.yml +0 -26
  126. data/Guardfile +0 -43
  127. data/gems/README.md +0 -28
  128. data/gems/octoshark.gemfile +0 -4
  129. data/gems/rails3.gemfile +0 -5
  130. data/gems/rails4.gemfile +0 -4
  131. data/gems/rails5.gemfile +0 -4
  132. data/gems/rails6.gemfile +0 -4
  133. data/lib/scout_apm/agent/exit_handler.rb +0 -65
  134. data/lib/scout_apm/agent/preconditions.rb +0 -81
  135. data/lib/scout_apm/agent_context.rb +0 -261
  136. data/lib/scout_apm/auto_instrument/instruction_sequence.rb +0 -31
  137. data/lib/scout_apm/auto_instrument/layer.rb +0 -23
  138. data/lib/scout_apm/auto_instrument/parser.rb +0 -27
  139. data/lib/scout_apm/auto_instrument/rails.rb +0 -175
  140. data/lib/scout_apm/auto_instrument.rb +0 -5
  141. data/lib/scout_apm/background_job_integrations/legacy_sneakers.rb +0 -55
  142. data/lib/scout_apm/background_job_integrations/que.rb +0 -134
  143. data/lib/scout_apm/background_job_integrations/resque.rb +0 -88
  144. data/lib/scout_apm/background_job_integrations/shoryuken.rb +0 -124
  145. data/lib/scout_apm/background_job_integrations/sneakers.rb +0 -87
  146. data/lib/scout_apm/background_recorder.rb +0 -48
  147. data/lib/scout_apm/db_query_metric_set.rb +0 -97
  148. data/lib/scout_apm/db_query_metric_stats.rb +0 -102
  149. data/lib/scout_apm/debug.rb +0 -37
  150. data/lib/scout_apm/detailed_trace.rb +0 -217
  151. data/lib/scout_apm/error.rb +0 -27
  152. data/lib/scout_apm/error_service/error_buffer.rb +0 -39
  153. data/lib/scout_apm/error_service/error_record.rb +0 -211
  154. data/lib/scout_apm/error_service/ignored_exceptions.rb +0 -66
  155. data/lib/scout_apm/error_service/middleware.rb +0 -32
  156. data/lib/scout_apm/error_service/notifier.rb +0 -33
  157. data/lib/scout_apm/error_service/payload.rb +0 -47
  158. data/lib/scout_apm/error_service/periodic_work.rb +0 -17
  159. data/lib/scout_apm/error_service/railtie.rb +0 -11
  160. data/lib/scout_apm/error_service/sidekiq.rb +0 -80
  161. data/lib/scout_apm/error_service.rb +0 -32
  162. data/lib/scout_apm/extensions/config.rb +0 -87
  163. data/lib/scout_apm/extensions/transaction_callback_payload.rb +0 -74
  164. data/lib/scout_apm/git_revision.rb +0 -59
  165. data/lib/scout_apm/instrument_manager.rb +0 -88
  166. data/lib/scout_apm/instruments/action_view.rb +0 -141
  167. data/lib/scout_apm/instruments/http.rb +0 -48
  168. data/lib/scout_apm/instruments/memcached.rb +0 -43
  169. data/lib/scout_apm/instruments/resque.rb +0 -39
  170. data/lib/scout_apm/instruments/samplers.rb +0 -11
  171. data/lib/scout_apm/layer_children_set.rb +0 -86
  172. data/lib/scout_apm/layer_converters/database_converter.rb +0 -70
  173. data/lib/scout_apm/layer_converters/find_layer_by_type.rb +0 -38
  174. data/lib/scout_apm/layer_converters/histograms.rb +0 -15
  175. data/lib/scout_apm/layer_converters/trace_converter.rb +0 -184
  176. data/lib/scout_apm/limited_layer.rb +0 -126
  177. data/lib/scout_apm/logger.rb +0 -158
  178. data/lib/scout_apm/periodic_work.rb +0 -47
  179. data/lib/scout_apm/rack.rb +0 -26
  180. data/lib/scout_apm/remote/message.rb +0 -27
  181. data/lib/scout_apm/remote/recorder.rb +0 -57
  182. data/lib/scout_apm/remote/router.rb +0 -49
  183. data/lib/scout_apm/remote/server.rb +0 -60
  184. data/lib/scout_apm/reporting.rb +0 -143
  185. data/lib/scout_apm/serializers/db_query_serializer_to_json.rb +0 -15
  186. data/lib/scout_apm/serializers/histograms_serializer_to_json.rb +0 -21
  187. data/lib/scout_apm/synchronous_recorder.rb +0 -30
  188. data/lib/scout_apm/tasks/doctor.rb +0 -75
  189. data/lib/scout_apm/tasks/support.rb +0 -22
  190. data/lib/scout_apm/transaction.rb +0 -13
  191. data/lib/scout_apm/transaction_time_consumed.rb +0 -51
  192. data/lib/scout_apm/utils/gzip_helper.rb +0 -24
  193. data/lib/scout_apm/utils/marshal_logging.rb +0 -90
  194. data/lib/scout_apm/utils/numbers.rb +0 -14
  195. data/lib/scout_apm/utils/scm.rb +0 -14
  196. data/lib/tasks/doctor.rake +0 -11
  197. data/test/tmp/README.md +0 -17
  198. data/test/unit/agent_context_test.rb +0 -15
  199. data/test/unit/auto_instrument/assignments-instrumented.rb +0 -31
  200. data/test/unit/auto_instrument/assignments.rb +0 -31
  201. data/test/unit/auto_instrument/controller-ast.txt +0 -57
  202. data/test/unit/auto_instrument/controller-instrumented.rb +0 -49
  203. data/test/unit/auto_instrument/controller.rb +0 -49
  204. data/test/unit/auto_instrument/rescue_from-instrumented.rb +0 -13
  205. data/test/unit/auto_instrument/rescue_from.rb +0 -13
  206. data/test/unit/auto_instrument_test.rb +0 -54
  207. data/test/unit/db_query_metric_set_test.rb +0 -67
  208. data/test/unit/db_query_metric_stats_test.rb +0 -113
  209. data/test/unit/error_service/error_buffer_test.rb +0 -25
  210. data/test/unit/error_service/ignored_exceptions_test.rb +0 -49
  211. data/test/unit/extensions/periodic_callbacks_test.rb +0 -58
  212. data/test/unit/extensions/transaction_callbacks_test.rb +0 -58
  213. data/test/unit/fake_store_test.rb +0 -10
  214. data/test/unit/git_revision_test.rb +0 -15
  215. data/test/unit/instruments/active_record_test.rb +0 -40
  216. data/test/unit/instruments/net_http_test.rb +0 -27
  217. data/test/unit/instruments/percentile_sampler_test.rb +0 -133
  218. data/test/unit/layer_children_set_test.rb +0 -97
  219. data/test/unit/layer_converters/depth_first_walker_test.rb +0 -70
  220. data/test/unit/layer_converters/metric_converter_test.rb +0 -22
  221. data/test/unit/layer_converters/stubs.rb +0 -33
  222. data/test/unit/limited_layer_test.rb +0 -53
  223. data/test/unit/logger_test.rb +0 -69
  224. data/test/unit/remote/test_message.rb +0 -13
  225. data/test/unit/remote/test_router.rb +0 -33
  226. data/test/unit/remote/test_server.rb +0 -15
  227. data/test/unit/request_histograms_test.rb +0 -17
  228. data/test/unit/tracer_test.rb +0 -76
  229. data/test/unit/tracked_request_test.rb +0 -71
  230. data/test/unit/transaction_test.rb +0 -14
  231. data/test/unit/transaction_time_consumed_test.rb +0 -46
  232. data/test/unit/utils/numbers_test.rb +0 -15
  233. data/test/unit/utils/scm.rb +0 -17
@@ -1,48 +0,0 @@
1
- # Provide a background thread queue to do the processing of
2
- # TrackedRequest objects, to remove it from the hot-path of returning a
3
- # web response
4
-
5
- module ScoutApm
6
- class BackgroundRecorder
7
- attr_reader :context
8
-
9
- attr_reader :queue
10
- attr_reader :thread
11
-
12
- def initialize(context)
13
- @context = context
14
- @queue = Queue.new
15
- end
16
-
17
- def logger
18
- context.logger
19
- end
20
-
21
- def start
22
- logger.info("Starting BackgroundRecorder")
23
- @thread = Thread.new(&method(:thread_func))
24
- self
25
- end
26
-
27
- def stop
28
- @thread.kill
29
- end
30
-
31
- def record!(request)
32
- start unless @thread.alive?
33
- @queue.push(request)
34
- end
35
-
36
- def thread_func
37
- while req = queue.pop
38
- begin
39
- logger.debug("recording in thread. Queue size: #{queue.size}")
40
- # For now, just proxy right back into the TrackedRequest object's record function
41
- req.record!
42
- rescue => e
43
- logger.warn("Error in BackgroundRecorder - #{e.message} : #{e.backtrace}")
44
- end
45
- end
46
- end
47
- end
48
- end
@@ -1,97 +0,0 @@
1
- # Note, this class must be Marshal Dumpable
2
- module ScoutApm
3
- class DbQueryMetricSet
4
- include Enumerable
5
-
6
- attr_reader :metrics # the raw metrics. You probably want #metrics_to_report
7
-
8
- def marshal_dump
9
- [ @metrics ]
10
- end
11
-
12
- def marshal_load(array)
13
- @metrics = array.first
14
- @context = ScoutApm::Agent.instance.context
15
- end
16
-
17
- def initialize(context)
18
- @context = context
19
-
20
- # A hash of DbQueryMetricStats values, keyed by DbQueryMetricStats.key
21
- @metrics = Hash.new
22
- end
23
-
24
- # Need to look this up again if we end up as nil. Which I guess can happen
25
- # after a Marshal load?
26
- def context
27
- @context ||= ScoutApm::Agent.instance.context
28
- end
29
-
30
- def each
31
- metrics.each do |_key, db_query_metric_stat|
32
- yield db_query_metric_stat
33
- end
34
- end
35
-
36
- # Looks up a DbQueryMetricStats instance in the +@metrics+ hash. Sets the value to +other+ if no key
37
- # Returns a DbQueryMetricStats instance
38
- def lookup(other)
39
- metrics[other.key] ||= other
40
- end
41
-
42
- # Take another set, and merge it with this one
43
- def combine!(other)
44
- other.each do |metric|
45
- self << metric
46
- end
47
- self
48
- end
49
-
50
- # Add a single DbQueryMetricStats object to this set.
51
- #
52
- # Looks up an existing one under this key and merges, or just saves a new
53
- # one under the key
54
- def <<(stat)
55
- existing_stat = metrics[stat.key]
56
- if existing_stat
57
- existing_stat.combine!(stat)
58
- elsif at_limit?
59
- # We're full up, can't add any more.
60
- # Should I log this? It may get super noisy?
61
- else
62
- metrics[stat.key] = stat
63
- end
64
- end
65
-
66
- def increment_transaction_count!
67
- metrics.each do |_key, db_query_metric_stat|
68
- db_query_metric_stat.increment_transaction_count!
69
- end
70
- end
71
-
72
- def metrics_to_report
73
- report_limit = context.config.value('database_metric_report_limit')
74
- if metrics.size > report_limit
75
- metrics.
76
- values.
77
- sort_by {|stat| stat.call_time }.
78
- reverse.
79
- take(report_limit)
80
- else
81
- metrics.values
82
- end
83
- end
84
-
85
- def inspect
86
- metrics.map {|key, metric|
87
- "#{key.inspect} - Count: #{metric.call_count}, Total Time: #{"%.2f" % metric.call_time}"
88
- }.join("\n")
89
- end
90
-
91
- def at_limit?
92
- @limit ||= context.config.value('database_metric_limit')
93
- metrics.size >= @limit
94
- end
95
-
96
- end
97
- end
@@ -1,102 +0,0 @@
1
- module ScoutApm
2
- class DbQueryMetricStats
3
-
4
- DEFAULT_HISTOGRAM_SIZE = 50
5
-
6
- attr_reader :model_name
7
- attr_reader :operation
8
- attr_reader :scope
9
-
10
- attr_reader :transaction_count
11
-
12
- attr_reader :call_count
13
- attr_reader :call_time
14
- attr_reader :rows_returned
15
-
16
- attr_reader :min_call_time
17
- attr_reader :max_call_time
18
-
19
- attr_reader :min_rows_returned
20
- attr_reader :max_rows_returned
21
-
22
- attr_reader :histogram
23
-
24
- def initialize(model_name, operation, scope, call_count, call_time, rows_returned)
25
- @model_name = model_name
26
- @operation = operation
27
-
28
- @call_count = call_count
29
-
30
- @call_time = call_time
31
- @min_call_time = call_time
32
- @max_call_time = call_time
33
-
34
- @rows_returned = rows_returned
35
- @min_rows_returned = rows_returned
36
- @max_rows_returned = rows_returned
37
-
38
- # Should we have a histogram for timing, and one for rows_returned?
39
- # This histogram is for call_time
40
- @histogram = NumericHistogram.new(DEFAULT_HISTOGRAM_SIZE)
41
- @histogram.add(call_time)
42
-
43
- @transaction_count = 0
44
-
45
- @scope = scope
46
- end
47
-
48
- # Merge data in this scope. Used in DbQueryMetricSet
49
- def key
50
- @key ||= [model_name, operation, scope]
51
- end
52
-
53
- # Combine data from another DbQueryMetricStats into +self+. Modifies and returns +self+
54
- def combine!(other)
55
- return self if other == self
56
-
57
- @transaction_count += other.transaction_count
58
- @call_count += other.call_count
59
- @rows_returned += other.rows_returned
60
- @call_time += other.call_time
61
-
62
- @min_call_time = other.min_call_time if @min_call_time.zero? or other.min_call_time < @min_call_time
63
- @max_call_time = other.max_call_time if other.max_call_time > @max_call_time
64
-
65
- @min_rows_returned = other.min_rows_returned if @min_rows_returned.zero? or other.min_rows_returned < @min_rows_returned
66
- @max_rows_returned = other.max_rows_returned if other.max_rows_returned > @max_rows_returned
67
-
68
- @histogram.combine!(other.histogram)
69
- self
70
- end
71
-
72
- def as_json
73
- json_attributes = [
74
- :model_name,
75
- :operation,
76
- :scope,
77
-
78
- :transaction_count,
79
- :call_count,
80
-
81
- :histogram,
82
- :call_time,
83
- :max_call_time,
84
- :min_call_time,
85
-
86
- :max_rows_returned,
87
- :min_rows_returned,
88
- :rows_returned,
89
- ]
90
-
91
- ScoutApm::AttributeArranger.call(self, json_attributes)
92
- end
93
-
94
- # Called by the Set on each DbQueryMetricStats object that it holds, only
95
- # once during the recording of a transaction.
96
- #
97
- # Don't call elsewhere, and don't set to 1 in the initializer.
98
- def increment_transaction_count!
99
- @transaction_count += 1
100
- end
101
- end
102
- end
@@ -1,37 +0,0 @@
1
- module ScoutApm
2
- class Debug
3
- # see self.instance
4
- @@instance = nil
5
-
6
- def self.instance
7
- @@instance ||= new
8
- end
9
-
10
- def register_periodic_hook(&hook)
11
- @periodic_hooks << hook
12
- end
13
-
14
- def call_periodic_hooks
15
- @periodic_hooks.each do |hook|
16
- begin
17
- hook.call
18
- rescue => e
19
- logger.info("Periodic debug hook failed to run: #{e}\n\t#{e.backtrace.join("\n\t")}")
20
- end
21
- end
22
- rescue
23
- # Something went super wrong for the inner rescue to not catch this. Just
24
- # swallow the error. The debug tool should never crash the app.
25
- end
26
-
27
- private
28
-
29
- def initialize
30
- @periodic_hooks = []
31
- end
32
-
33
- def logger
34
- ScoutApm::Agent.instance.context.logger
35
- end
36
- end
37
- end
@@ -1,217 +0,0 @@
1
- # DetailedTrace contains all details about a certain transaction, spans with
2
- # start & stop times, tags, etc.
3
-
4
- # {
5
- # "version": 1,
6
- # "identity": {
7
- # "transaction_id": "req-....",
8
- # "revision": "abcdef",
9
- # "start_instant": "01-01-01T00:00:00.0000Z",
10
- # "stop_instant": "01-01-01T00:00:01.0000Z",
11
- # "type": "Web",
12
- # "naming": {
13
- # "path": "/users",
14
- # "code": "UsersController#index",
15
- # },
16
- # "score": {
17
- # "total": 10.5,
18
- # "percentile": 4.5,
19
- # "age": 2.0,
20
- # "memory_delta": 3,
21
- # "allocations": 1
22
- # }
23
- # },
24
- #
25
- # "tags": {
26
- # "allocations": 1000
27
- # },
28
- #
29
- # "spans": [
30
- # ...
31
- # ]
32
-
33
- class DetailedTrace
34
- attr_reader :spans
35
- attr_reader :tags
36
-
37
- attr_reader :transaction_id
38
- attr_reader :revision
39
- attr_reader :start_instant
40
- attr_reader :stop_instant
41
- attr_reader :duration
42
- attr_reader :type # "Web" or "Job"
43
- attr_reader :host
44
-
45
- attr_reader :path # /users/1
46
- attr_reader :code # UsersController#show or similar
47
-
48
- attr_reader :total_score
49
- attr_reader :percentile_score
50
- attr_reader :age_score
51
- attr_reader :memory_delta_score
52
- attr_reader :memory_allocations_score
53
-
54
- VERSION = 1
55
-
56
- def initialize(transaction_id, revision, host, start_instant, stop_instant, type, path, code, spans, tags)
57
- @spans = spans
58
- @tags = DetailedTraceTags(tags)
59
-
60
- @transaction_id = transaction_id
61
- @revision = revision
62
- @host = host
63
- @start_instant = start_instant
64
- @stop_instant = stop_instant
65
- @type = type
66
-
67
- @path = path
68
- @code = code
69
-
70
- @total_score = 0
71
- @percentile_score = 0
72
- @age_score = 0
73
- @memory_delta_score = 0
74
- @memory_allocations_score = 0
75
-
76
- end
77
-
78
- def as_json(*)
79
- {
80
- :version => VERSION,
81
- :identity => {
82
- :transaction_id => transaction_id,
83
- :revision => revision,
84
- :host => host,
85
- :start_instant => start_instant.iso8601(6),
86
- :stop_instant => stop_instant.iso8601(6),
87
- :type => type,
88
- :naming => {
89
- :path => path,
90
- :code => code,
91
- },
92
- :score => {
93
- :total => total_score,
94
- :percentile => percentile_score,
95
- :age => age_score,
96
- :memory_delta => memory_delta_score,
97
- :allocations => memory_allocations_score,
98
- }
99
- },
100
- :tags => tags.as_json,
101
- :spans => spans.map{|span| span.as_json},
102
- }
103
- end
104
-
105
- ########################
106
- # Scorable interface
107
- #
108
- # Needed so we can merge ScoredItemSet instances
109
- def call
110
- self
111
- end
112
-
113
- def name
114
- code
115
- end
116
-
117
- def score
118
- @total_score
119
- end
120
-
121
- end
122
-
123
- ##########
124
- # SPAN #
125
- ##########
126
-
127
- #
128
- # {
129
- # "type": "Standard",
130
- # "identity": {
131
- # "id": "....",
132
- # "parent_id": "....",
133
- # "start_time": "01-01-01T00:00:00.0000Z",
134
- # "stop_time": "01-01-01T00:00:00.0001Z",
135
- # "operation": "SQL/User/find"
136
- # },
137
- # "tags": {
138
- # "allocations": 1000,
139
- # "db.statement": "SELECT * FROM users where id = 1",
140
- # "db.rows": 1,
141
- # "backtrace": [ {
142
- # "file": "app/controllers/users_controller.rb",
143
- # "line": 10,
144
- # "function": "index"
145
- # } ]
146
- # }
147
- class DetailedTraceSpan
148
- attr_reader :tags
149
-
150
- attr_reader :span_type
151
- attr_reader :span_id, :parent_id
152
- attr_reader :start_instant, :stop_instant
153
-
154
- # What is the "name" of this span.
155
- #
156
- # Examples:
157
- # SQL/User/find
158
- # Controller/Users/index
159
- # HTTP/GET/example.com
160
- attr_reader :operation
161
-
162
- def initialize(span_id, parent_id, start_instant, stop_instant, operation, tags)
163
- # This will be dynamic when we implement limited spans
164
- @span_type = "Standard"
165
-
166
- @span_id = span_id
167
- @parent_id = parent_id
168
-
169
- @start_instant = start_instant
170
- @stop_instant = stop_instant
171
- @operation = operation
172
- @tags = DetailedTraceTags(tags)
173
- end
174
-
175
- def as_json(*)
176
- {
177
- :type => @span_type,
178
- :identity => {
179
- :id => span_id,
180
- :parent_id => parent_id,
181
- :start_instant => start_instant.iso8601(6),
182
- :stop_instant => stop_instant.iso8601(6),
183
- :operation => operation,
184
- },
185
- :tags => @tags.as_json,
186
- }
187
- end
188
- end
189
-
190
-
191
- #############
192
- # content #
193
- #############
194
-
195
- # Tags for either a request, or a span
196
- class DetailedTraceTags
197
- attr_reader :tags
198
-
199
- def initialize(hash)
200
- @tags = hash
201
- end
202
-
203
- # @tags is already a hash, so no conversion needed
204
- def as_json(*)
205
- @tags
206
- end
207
- end
208
-
209
- # Converter function to turn an input into a DetailedTraceTags object
210
- def DetailedTraceTags(arg)
211
- if DetailedTraceTags === arg
212
- arg
213
- elsif Hash === arg
214
- DetailedTraceTags.new(arg)
215
- end
216
- end
217
-
@@ -1,27 +0,0 @@
1
- # Public API for the Scout Error Monitoring service
2
- #
3
- # See-Also ScoutApm::Transaction and ScoutApm::Tracing for APM related APIs
4
- module ScoutApm
5
- module Error
6
- # Capture an exception, optionally with an environment hash. This may be a
7
- # Rack environment, but is not required.
8
- def self.capture(exception, env={})
9
- context = ScoutApm::Agent.instance.context
10
-
11
- # Skip if error monitoring isn't enabled at all
12
- if ! context.config.value("errors_enabled")
13
- return false
14
- end
15
-
16
- # Skip if this one error is ignored
17
- if context.ignored_exceptions.ignored?(exception)
18
- return false
19
- end
20
-
21
- # Capture the error for further processing and shipping
22
- context.error_buffer.capture(exception, env)
23
-
24
- return true
25
- end
26
- end
27
- end
@@ -1,39 +0,0 @@
1
- # Holds onto exceptions, and moves them forward to shipping when appropriate
2
- module ScoutApm
3
- module ErrorService
4
- class ErrorBuffer
5
- include Enumerable
6
-
7
- attr_reader :agent_context
8
-
9
- def initialize(agent_context)
10
- @agent_context = agent_context
11
- @error_records = []
12
- @mutex = Monitor.new
13
- end
14
-
15
- def capture(exception, env)
16
- context = ScoutApm::Context.current
17
-
18
- @mutex.synchronize {
19
- @error_records << ErrorRecord.new(agent_context, exception, env, context)
20
- }
21
- end
22
-
23
- def get_and_reset_error_records
24
- @mutex.synchronize {
25
- ret = @error_records
26
- @error_records = []
27
- ret
28
- }
29
- end
30
-
31
- # Enables enumerable - for count and each and similar methods
32
- def each
33
- @error_records.each do |error_record|
34
- yield error_record
35
- end
36
- end
37
- end
38
- end
39
- end