scout_apm 2.3.5 → 2.4.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.markdown +0 -23
  3. data/lib/scout_apm.rb +21 -10
  4. data/lib/scout_apm/agent.rb +98 -336
  5. data/lib/scout_apm/agent/exit_handler.rb +64 -0
  6. data/lib/scout_apm/agent/preconditions.rb +69 -0
  7. data/lib/scout_apm/agent_context.rb +226 -0
  8. data/lib/scout_apm/app_server_load.rb +20 -18
  9. data/lib/scout_apm/background_job_integrations/resque.rb +7 -8
  10. data/lib/scout_apm/background_job_integrations/sidekiq.rb +2 -8
  11. data/lib/scout_apm/background_recorder.rb +8 -3
  12. data/lib/scout_apm/background_worker.rb +14 -7
  13. data/lib/scout_apm/config.rb +35 -29
  14. data/lib/scout_apm/context.rb +11 -4
  15. data/lib/scout_apm/db_query_metric_set.rb +17 -5
  16. data/lib/scout_apm/debug.rb +1 -1
  17. data/lib/scout_apm/environment.rb +10 -14
  18. data/lib/scout_apm/framework_integrations/sinatra.rb +1 -1
  19. data/lib/scout_apm/git_revision.rb +13 -8
  20. data/lib/scout_apm/histogram.rb +1 -1
  21. data/lib/scout_apm/instant/middleware.rb +7 -7
  22. data/lib/scout_apm/instant_reporting.rb +7 -7
  23. data/lib/scout_apm/instrument_manager.rb +87 -0
  24. data/lib/scout_apm/instruments/action_controller_rails_2.rb +12 -7
  25. data/lib/scout_apm/instruments/action_controller_rails_3_rails4.rb +16 -11
  26. data/lib/scout_apm/instruments/action_view.rb +11 -7
  27. data/lib/scout_apm/instruments/active_record.rb +28 -51
  28. data/lib/scout_apm/instruments/elasticsearch.rb +10 -6
  29. data/lib/scout_apm/instruments/grape.rb +12 -8
  30. data/lib/scout_apm/instruments/http_client.rb +11 -10
  31. data/lib/scout_apm/instruments/influxdb.rb +10 -6
  32. data/lib/scout_apm/instruments/middleware_detailed.rb +11 -5
  33. data/lib/scout_apm/instruments/middleware_summary.rb +11 -5
  34. data/lib/scout_apm/instruments/mongoid.rb +10 -5
  35. data/lib/scout_apm/instruments/moped.rb +11 -6
  36. data/lib/scout_apm/instruments/net_http.rb +11 -9
  37. data/lib/scout_apm/instruments/percentile_sampler.rb +8 -6
  38. data/lib/scout_apm/instruments/process/process_cpu.rb +8 -4
  39. data/lib/scout_apm/instruments/process/process_memory.rb +15 -10
  40. data/lib/scout_apm/instruments/rails_router.rb +12 -6
  41. data/lib/scout_apm/instruments/redis.rb +10 -6
  42. data/lib/scout_apm/instruments/samplers.rb +11 -0
  43. data/lib/scout_apm/instruments/sinatra.rb +5 -4
  44. data/lib/scout_apm/layaway.rb +26 -39
  45. data/lib/scout_apm/layaway_file.rb +8 -3
  46. data/lib/scout_apm/layer.rb +1 -1
  47. data/lib/scout_apm/layer_converters/converter_base.rb +4 -2
  48. data/lib/scout_apm/layer_converters/database_converter.rb +1 -1
  49. data/lib/scout_apm/layer_converters/histograms.rb +2 -2
  50. data/lib/scout_apm/layer_converters/slow_job_converter.rb +4 -3
  51. data/lib/scout_apm/layer_converters/slow_request_converter.rb +5 -4
  52. data/lib/scout_apm/logger.rb +143 -0
  53. data/lib/scout_apm/middleware.rb +7 -9
  54. data/lib/scout_apm/periodic_work.rb +28 -0
  55. data/lib/scout_apm/remote/server.rb +0 -2
  56. data/lib/scout_apm/reporter.rb +14 -8
  57. data/lib/scout_apm/reporting.rb +135 -0
  58. data/lib/scout_apm/request_manager.rb +4 -7
  59. data/lib/scout_apm/serializers/payload_serializer.rb +1 -1
  60. data/lib/scout_apm/slow_job_policy.rb +6 -2
  61. data/lib/scout_apm/slow_job_record.rb +5 -5
  62. data/lib/scout_apm/slow_request_policy.rb +6 -2
  63. data/lib/scout_apm/slow_transaction.rb +5 -5
  64. data/lib/scout_apm/store.rb +22 -16
  65. data/lib/scout_apm/synchronous_recorder.rb +7 -3
  66. data/lib/scout_apm/tasks/doctor.rb +75 -0
  67. data/lib/scout_apm/tasks/support.rb +22 -0
  68. data/lib/scout_apm/tracer.rb +5 -5
  69. data/lib/scout_apm/tracked_request.rb +23 -35
  70. data/lib/scout_apm/utils/backtrace_parser.rb +1 -1
  71. data/lib/scout_apm/utils/installed_gems.rb +7 -3
  72. data/lib/scout_apm/utils/klass_helper.rb +8 -2
  73. data/lib/scout_apm/utils/scm.rb +1 -1
  74. data/lib/scout_apm/utils/sql_sanitizer.rb +4 -6
  75. data/lib/scout_apm/version.rb +1 -1
  76. data/lib/tasks/doctor.rake +11 -0
  77. data/test/test_helper.rb +15 -2
  78. data/test/unit/agent_test.rb +1 -54
  79. data/test/unit/config_test.rb +9 -5
  80. data/test/unit/context_test.rb +4 -4
  81. data/test/unit/db_query_metric_set_test.rb +11 -4
  82. data/test/unit/fake_store_test.rb +1 -1
  83. data/test/unit/git_revision_test.rb +3 -3
  84. data/test/unit/instruments/net_http_test.rb +2 -1
  85. data/test/unit/instruments/percentile_sampler_test.rb +5 -9
  86. data/test/unit/layaway_test.rb +10 -5
  87. data/test/unit/layer_converters/metric_converter_test.rb +2 -2
  88. data/test/unit/slow_request_policy_test.rb +7 -3
  89. data/test/unit/sql_sanitizer_test.rb +0 -6
  90. data/test/unit/store_test.rb +11 -8
  91. metadata +15 -7
  92. data/lib/scout_apm/agent/logging.rb +0 -74
  93. data/lib/scout_apm/agent/reporting.rb +0 -129
  94. data/lib/scout_apm/utils/null_logger.rb +0 -13
@@ -1,74 +0,0 @@
1
- # Contains methods specific to logging (initializing the log file, applying the log level, applying the log format, etc.)
2
- module ScoutApm
3
- class Agent
4
- module Logging
5
- def default_log_path
6
- "#{environment.root}/log"
7
- end
8
-
9
- def init_logger(opts={})
10
- if opts[:force]
11
- @log_file = nil
12
- @logger = nil
13
- end
14
-
15
- begin
16
- @log_file ||= determine_log_destination
17
- rescue => e
18
- end
19
-
20
- begin
21
- @logger ||= Logger.new(@log_file)
22
- @logger.level = log_level
23
- apply_log_format
24
- rescue Exception => e
25
- @logger = Logger.new(STDOUT)
26
- apply_log_format
27
- @logger.error "Unable to open log file for writing: #{e.message}. Falling back to STDOUT"
28
- end
29
- @logger
30
- end
31
-
32
- def apply_log_format
33
- def logger.format_message(severity, timestamp, progname, msg)
34
- # since STDOUT isn't exclusive like the scout_apm.log file, apply a prefix.
35
- prefix = @logdev.dev == STDOUT ? "[Scout] " : ''
36
- prefix + "[#{Utils::Time.to_s(timestamp)} #{ScoutApm::Agent.instance.environment.hostname} (#{$$})] #{severity} : #{msg}\n"
37
- end
38
- end
39
-
40
- def log_level
41
- case config.value('log_level').downcase
42
- when "debug" then Logger::DEBUG
43
- when "info" then Logger::INFO
44
- when "warn" then Logger::WARN
45
- when "error" then Logger::ERROR
46
- when "fatal" then Logger::FATAL
47
- else Logger::INFO
48
- end
49
- end
50
-
51
- def determine_log_destination
52
- case true
53
- when wants_stdout? then STDOUT
54
- when wants_stderr? then STDERR
55
- else "#{log_file_path}/scout_apm.log"
56
- end
57
- end
58
-
59
- def wants_stdout?
60
- config.value('log_file_path').to_s.upcase == 'STDOUT' || environment.platform_integration.log_to_stdout?
61
- end
62
-
63
- def wants_stderr?
64
- config.value('log_file_path').to_s.upcase == 'STDERR'
65
- end
66
-
67
- def log_file_path
68
- config.value('log_file_path') || default_log_path
69
- end
70
- end
71
- include Logging
72
- end
73
- end
74
-
@@ -1,129 +0,0 @@
1
- # Methods related to sending metrics to scoutapp.com.
2
- module ScoutApm
3
- class Agent
4
- module Reporting
5
- def reporter
6
- @reporter ||= ScoutApm::Reporter.new(:checkin, config, logger)
7
- end
8
-
9
- # The data moves through a treadmill of reporting, coordinating several Rails processes by using an external file.
10
- # * During the minute it is being recorded by the instruments, it gets
11
- # recorded into the ram of each process (in the Store class).
12
- # * The minute after, each process writes its own metrics to a shared LayawayFile
13
- # * The minute after that, the first process to wake up pushes the combined
14
- # data to the server, and wipes it. Next processes don't have anything to do.
15
- #
16
- # At any given point, there is data in each of those steps, moving its way through the process
17
- def process_metrics
18
- # Write the previous minute's data to the shared-across-process layaway file.
19
- store.write_to_layaway(layaway)
20
-
21
- # Attempt to send 2 minutes ago's data up to the server. This
22
- # only acctually occurs if this process is the first to wake up this
23
- # minute.
24
- report_to_server
25
- end
26
-
27
- # In a running app, one process will get the period ready for delivery, the others will see 0.
28
- def report_to_server
29
- period_to_report = ScoutApm::StoreReportingPeriodTimestamp.minutes_ago(2)
30
-
31
- logger.debug("Attempting to claim #{period_to_report.to_s}")
32
-
33
- did_write = layaway.with_claim(period_to_report) do |rps|
34
- logger.debug("Succeeded claiming #{period_to_report.to_s}")
35
-
36
- begin
37
- merged = rps.inject { |memo, rp| memo.merge(rp) }
38
- logger.debug("Merged #{rps.length} reporting periods, delivering")
39
- deliver_period(merged)
40
- true
41
- rescue => e
42
- logger.debug("Error merging reporting periods #{e.message}")
43
- logger.debug("Error merging reporting periods #{e.backtrace}")
44
- false
45
- end
46
-
47
- end
48
-
49
- if !did_write
50
- logger.debug("Failed to obtain claim for #{period_to_report.to_s}")
51
- end
52
-
53
- end
54
-
55
-
56
- def deliver_period(reporting_period)
57
- metrics = reporting_period.metrics_payload
58
- slow_transactions = reporting_period.slow_transactions_payload
59
- jobs = reporting_period.jobs
60
- slow_jobs = reporting_period.slow_jobs_payload
61
- histograms = reporting_period.histograms
62
- db_query_metrics = reporting_period.db_query_metrics_payload
63
-
64
- metadata = {
65
- :app_root => ScoutApm::Environment.instance.root.to_s,
66
- :unique_id => ScoutApm::Utils::UniqueId.simple,
67
- :agent_version => ScoutApm::VERSION,
68
- :agent_time => reporting_period.timestamp.to_s,
69
- :agent_pid => Process.pid,
70
- :platform => "ruby",
71
- }
72
-
73
- log_deliver(metrics, slow_transactions, metadata, slow_jobs, histograms)
74
-
75
- payload = ScoutApm::Serializers::PayloadSerializer.serialize(metadata, metrics, slow_transactions, jobs, slow_jobs, histograms, db_query_metrics)
76
- logger.debug("Sending payload w/ Headers: #{headers.inspect}")
77
-
78
- reporter.report(payload, headers)
79
- rescue => e
80
- logger.warn "Error on checkin"
81
- logger.info e.message
82
- logger.debug e.backtrace
83
- end
84
-
85
- def log_deliver(metrics, slow_transactions, metadata, jobs_traces, histograms)
86
- total_request_count = metrics.
87
- select { |meta,stats| meta.metric_name =~ /\AController/ }.
88
- inject(0) {|sum, (_, stat)| sum + stat.call_count }
89
-
90
- memory = metrics.
91
- find {|meta,stats| meta.metric_name =~ /\AMemory/ }
92
- process_log_str = if memory
93
- "Recorded from #{memory.last.call_count} processes"
94
- else
95
- "Recorded across (unknown) processes"
96
- end
97
-
98
- time_clause = "[#{Time.parse(metadata[:agent_time]).strftime("%H:%M")}]"
99
- metrics_clause = "#{metrics.length} Metrics for #{total_request_count} requests"
100
- slow_trans_clause = "#{slow_transactions.length} Slow Transaction Traces"
101
- job_clause = "#{jobs_traces.length} Job Traces"
102
- histogram_clause = "#{histograms.length} Histograms"
103
-
104
- logger.info "#{time_clause} Delivering #{metrics_clause} and #{slow_trans_clause} and #{job_clause}, #{process_log_str}."
105
- logger.debug("\n\nMetrics: #{metrics.pretty_inspect}\nSlowTrans: #{slow_transactions.pretty_inspect}\nMetadata: #{metadata.inspect.pretty_inspect}\n\n")
106
- end
107
-
108
- # TODO: Move this into PayloadSerializer?
109
- def headers
110
- if ScoutApm::Agent.instance.config.value("report_format") == 'json'
111
- headers = {'Content-Type' => 'application/json'}
112
- else
113
- headers = {}
114
- end
115
- end
116
-
117
- # Before reporting, lookup metric_id for each MetricMeta. This speeds up
118
- # reporting on the server-side.
119
- def add_metric_ids(metrics)
120
- metrics.each do |meta,stats|
121
- if metric_id = metric_lookup[meta]
122
- meta.metric_id = metric_id
123
- end
124
- end
125
- end
126
- end
127
- include Reporting
128
- end
129
- end
@@ -1,13 +0,0 @@
1
- require 'logger'
2
-
3
- module ScoutApm
4
- module Utils
5
- class NullLogger < Logger
6
- def initialize(*args)
7
- end
8
-
9
- def add(*args, &block)
10
- end
11
- end
12
- end
13
- end