scout_apm 2.6.6 → 4.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +49 -0
  3. data/.rubocop.yml +2 -5
  4. data/.travis.yml +3 -7
  5. data/CHANGELOG.markdown +45 -0
  6. data/Gemfile +1 -8
  7. data/gems/rails6.gemfile +1 -1
  8. data/lib/scout_apm.rb +22 -1
  9. data/lib/scout_apm/agent.rb +22 -0
  10. data/lib/scout_apm/agent_context.rb +14 -2
  11. data/lib/scout_apm/background_job_integrations/sidekiq.rb +2 -2
  12. data/lib/scout_apm/config.rb +17 -2
  13. data/lib/scout_apm/detailed_trace.rb +2 -1
  14. data/lib/scout_apm/environment.rb +16 -1
  15. data/lib/scout_apm/error.rb +27 -0
  16. data/lib/scout_apm/error_service.rb +32 -0
  17. data/lib/scout_apm/error_service/error_buffer.rb +39 -0
  18. data/lib/scout_apm/error_service/error_record.rb +211 -0
  19. data/lib/scout_apm/error_service/ignored_exceptions.rb +66 -0
  20. data/lib/scout_apm/error_service/middleware.rb +32 -0
  21. data/lib/scout_apm/error_service/notifier.rb +33 -0
  22. data/lib/scout_apm/error_service/payload.rb +47 -0
  23. data/lib/scout_apm/error_service/periodic_work.rb +17 -0
  24. data/lib/scout_apm/error_service/railtie.rb +11 -0
  25. data/lib/scout_apm/error_service/sidekiq.rb +80 -0
  26. data/lib/scout_apm/extensions/transaction_callback_payload.rb +1 -1
  27. data/lib/scout_apm/instrument_manager.rb +1 -0
  28. data/lib/scout_apm/instruments/action_controller_rails_3_rails4.rb +47 -26
  29. data/lib/scout_apm/instruments/action_view.rb +21 -8
  30. data/lib/scout_apm/instruments/active_record.rb +17 -28
  31. data/lib/scout_apm/instruments/typhoeus.rb +88 -0
  32. data/lib/scout_apm/layer.rb +1 -1
  33. data/lib/scout_apm/middleware.rb +1 -1
  34. data/lib/scout_apm/remote/server.rb +13 -1
  35. data/lib/scout_apm/reporter.rb +8 -3
  36. data/lib/scout_apm/serializers/payload_serializer_to_json.rb +28 -10
  37. data/lib/scout_apm/slow_policy/age_policy.rb +33 -0
  38. data/lib/scout_apm/slow_policy/percent_policy.rb +22 -0
  39. data/lib/scout_apm/slow_policy/percentile_policy.rb +24 -0
  40. data/lib/scout_apm/slow_policy/policy.rb +21 -0
  41. data/lib/scout_apm/slow_policy/speed_policy.rb +16 -0
  42. data/lib/scout_apm/slow_request_policy.rb +18 -77
  43. data/lib/scout_apm/utils/sql_sanitizer.rb +1 -0
  44. data/lib/scout_apm/utils/sql_sanitizer_regex.rb +3 -3
  45. data/lib/scout_apm/utils/sql_sanitizer_regex_1_8_7.rb +1 -0
  46. data/lib/scout_apm/version.rb +1 -1
  47. data/scout_apm.gemspec +6 -6
  48. data/test/unit/agent_context_test.rb +29 -0
  49. data/test/unit/environment_test.rb +2 -2
  50. data/test/unit/error_service/error_buffer_test.rb +25 -0
  51. data/test/unit/error_service/ignored_exceptions_test.rb +49 -0
  52. data/test/unit/serializers/payload_serializer_test.rb +36 -0
  53. data/test/unit/slow_request_policy_test.rb +41 -13
  54. data/test/unit/sql_sanitizer_test.rb +38 -0
  55. metadata +26 -61
  56. data/lib/scout_apm/slow_job_policy.rb +0 -111
  57. data/test/unit/slow_job_policy_test.rb +0 -6
@@ -1,111 +0,0 @@
1
- # Long running class that determines if, and in how much detail a potentially
2
- # slow job should be recorded in
3
-
4
- module ScoutApm
5
- class SlowJobPolicy
6
- CAPTURE_TYPES = [
7
- CAPTURE_DETAIL = "capture_detail",
8
- CAPTURE_NONE = "capture_none",
9
- ]
10
-
11
- # Adjust speed points. See the function
12
- POINT_MULTIPLIER_SPEED = 0.25
13
-
14
- # For each minute we haven't seen an endpoint
15
- POINT_MULTIPLIER_AGE = 0.25
16
-
17
- # Outliers are worth up to "1000ms" of weight
18
- POINT_MULTIPLIER_PERCENTILE = 1.0
19
-
20
- # Points for an endpoint's who's throughput * response time is a large % of
21
- # overall time spent processing requests
22
- POINT_MULTIPLIER_PERCENT_TIME = 2.5
23
-
24
- # A hash of Job Names to the last time we stored a slow trace for it.
25
- #
26
- # Defaults to a start time that is pretty close to application boot time.
27
- # So the "age" of an endpoint we've never seen is the time the application
28
- # has been running.
29
- attr_reader :last_seen
30
-
31
- # The AgentContext we're running in
32
- attr_reader :context
33
-
34
- def initialize(context)
35
- @context = context
36
-
37
- zero_time = Time.now
38
- @last_seen = Hash.new { |h, k| h[k] = zero_time }
39
- end
40
-
41
- def stored!(request)
42
- last_seen[request.unique_name] = Time.now
43
- end
44
-
45
- # Determine if this job trace should be fully analyzed by scoring it
46
- # across several metrics, and then determining if that's good enough to
47
- # make it into this minute's payload.
48
- #
49
- # Due to the combining nature of the agent & layaway file, there's no
50
- # guarantee that a high scoring local champion will still be a winner when
51
- # they go up to "regionals" and are compared against the other processes
52
- # running on a node.
53
- def score(request)
54
- unique_name = request.unique_name
55
- if unique_name == :unknown
56
- return -1 # A negative score, should never be good enough to store.
57
- end
58
-
59
- total_time = request.root_layer.total_call_time
60
-
61
- # How long has it been since we've seen this?
62
- age = Time.now - last_seen[unique_name]
63
-
64
- # What approximate percentile was this request?
65
- percentile = context.request_histograms.approximate_quantile_of_value(unique_name, total_time)
66
-
67
- percent_of_total_time = context.transaction_time_consumed.percent_of_total(unique_name)
68
-
69
- return speed_points(total_time) + percentile_points(percentile) + age_points(age) + percent_time_points(percent_of_total_time)
70
- end
71
-
72
- private
73
-
74
- # Time in seconds
75
- # Logarithm keeps huge times from swamping the other metrics.
76
- # 1+ is necessary to keep the log function in positive territory.
77
- def speed_points(time)
78
- Math.log(1 + time) * POINT_MULTIPLIER_SPEED
79
- end
80
-
81
- def percentile_points(percentile)
82
- if percentile < 40
83
- 0.4 # Don't put much emphasis on capturing low percentiles.
84
- elsif percentile < 60
85
- 1.4 # Highest here to get mean traces
86
- elsif percentile < 90
87
- 0.7 # Between 60 & 90% is fine.
88
- elsif percentile >= 90
89
- 1.4 # Highest here to get 90+%ile traces
90
- else
91
- # impossible.
92
- percentile
93
- end
94
- end
95
-
96
- def age_points(age)
97
- age / 60.0 * POINT_MULTIPLIER_AGE
98
- end
99
-
100
- # Of the total time spent handling endpoints in this app, if this endpoint
101
- # is a higher percent, it should get more points.
102
- #
103
- # A: 20 calls @ 100ms each => 2 seconds of total time
104
- # B: 10 calls @ 100ms each => 1 second of total time
105
- #
106
- # Then A is 66% of the total call time
107
- def percent_time_points(percent) # Scale 0.0 - 1.0
108
- percent * POINT_MULTIPLIER_PERCENT_TIME
109
- end
110
- end
111
- end
@@ -1,6 +0,0 @@
1
- require 'test_helper'
2
-
3
- require 'scout_apm/slow_job_policy'
4
-
5
- class SlowJobPolicyTest < Minitest::Test
6
- end