oneapm_rpm 1.1.2 → 1.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/one_apm/agent.rb +185 -192
- data/lib/one_apm/agent/agent/connect.rb +17 -17
- data/lib/one_apm/agent/agent/container_data_manager.rb +14 -14
- data/lib/one_apm/agent/agent/forkable_dispatcher_functions.rb +6 -35
- data/lib/one_apm/agent/agent/helpers.rb +6 -17
- data/lib/one_apm/agent/agent/start.rb +27 -27
- data/lib/one_apm/agent/agent/start_worker_thread.rb +19 -51
- data/lib/one_apm/agent/busy_calculator.rb +8 -34
- data/lib/one_apm/agent/cross_app/cross_app_monitor.rb +10 -10
- data/lib/one_apm/agent/cross_app/cross_app_tracing.rb +14 -14
- data/lib/one_apm/agent/database.rb +8 -35
- data/lib/one_apm/agent/database/active_record_helper.rb +1 -1
- data/lib/one_apm/agent/datastores.rb +2 -109
- data/lib/one_apm/agent/datastores/metric_helper.rb +1 -1
- data/lib/one_apm/agent/datastores/mongo/metric_translator.rb +3 -3
- data/lib/one_apm/agent/datastores/mongo/statement_formatter.rb +2 -2
- data/lib/one_apm/agent/harvester.rb +3 -6
- data/lib/one_apm/agent/inbound_request_monitor.rb +2 -2
- data/lib/one_apm/agent/javascript_instrumentor.rb +28 -28
- data/lib/one_apm/agent/sampler.rb +1 -1
- data/lib/one_apm/agent/sampler_collection.rb +6 -9
- data/lib/one_apm/agent/samplers/cpu_sampler.rb +4 -4
- data/lib/one_apm/agent/samplers/delayed_job_sampler.rb +5 -5
- data/lib/one_apm/agent/samplers/memory_sampler.rb +5 -5
- data/lib/one_apm/agent/samplers/object_sampler.rb +1 -1
- data/lib/one_apm/agent/samplers/vm_sampler.rb +6 -6
- data/lib/one_apm/agent/synthetics_monitor.rb +2 -2
- data/lib/one_apm/agent/threading/agent_thread.rb +6 -6
- data/lib/one_apm/agent/threading/backtrace_service.rb +9 -9
- data/lib/one_apm/agent/threading/thread_profile.rb +3 -3
- data/lib/one_apm/collector/collector/helper.rb +10 -10
- data/lib/one_apm/collector/collector/http_connection.rb +14 -14
- data/lib/one_apm/collector/collector/server_methods.rb +12 -12
- data/lib/one_apm/collector/collector_service.rb +8 -8
- data/lib/one_apm/collector/commands/thread_profiler_session.rb +4 -4
- data/lib/one_apm/collector/commands/xray_session.rb +1 -1
- data/lib/one_apm/collector/commands/xray_session_collection.rb +10 -10
- data/lib/one_apm/collector/containers/agent_command_router.rb +7 -7
- data/lib/one_apm/collector/containers/custom_event_aggregator.rb +6 -6
- data/lib/one_apm/collector/containers/error_collector.rb +16 -16
- data/lib/one_apm/collector/containers/sql_sampler.rb +8 -11
- data/lib/one_apm/collector/containers/transaction_event_aggregator.rb +15 -15
- data/lib/one_apm/collector/containers/transaction_sampler.rb +14 -16
- data/lib/one_apm/{agent/pipe/pipe_service.rb → collector/forked_process_service.rb} +3 -3
- data/lib/one_apm/collector/stats_engine/gc_profiler.rb +3 -3
- data/lib/one_apm/collector/stats_engine/metric_stats.rb +4 -4
- data/lib/one_apm/collector/stats_engine/stats_hash.rb +2 -2
- data/lib/one_apm/configuration.rb +16 -16
- data/lib/one_apm/configuration/autostart.rb +4 -4
- data/lib/one_apm/configuration/default_source.rb +9 -9
- data/lib/one_apm/configuration/environment_source.rb +1 -1
- data/lib/one_apm/configuration/high_security_source.rb +1 -1
- data/lib/one_apm/configuration/yaml_source.rb +7 -7
- data/lib/one_apm/errors/noticed_error.rb +2 -2
- data/lib/one_apm/frameworks/external.rb +2 -0
- data/lib/one_apm/frameworks/rails.rb +8 -18
- data/lib/one_apm/frameworks/rails3.rb +1 -0
- data/lib/one_apm/frameworks/rails4.rb +2 -6
- data/lib/one_apm/frameworks/ruby.rb +7 -2
- data/lib/one_apm/frameworks/sinatra.rb +1 -2
- data/lib/one_apm/inst/3rd/active_merchant.rb +1 -1
- data/lib/one_apm/inst/3rd/acts_as_solr.rb +2 -2
- data/lib/one_apm/inst/3rd/authlogic.rb +1 -1
- data/lib/one_apm/inst/3rd/sunspot.rb +1 -1
- data/lib/one_apm/inst/background_job/active_job.rb +1 -1
- data/lib/one_apm/inst/background_job/delayed_job.rb +4 -4
- data/lib/one_apm/inst/background_job/event_machine_standalone.rb +2 -2
- data/lib/one_apm/inst/background_job/resque.rb +11 -11
- data/lib/one_apm/inst/background_job/sidekiq.rb +5 -5
- data/lib/one_apm/inst/dispatcher/passenger.rb +4 -4
- data/lib/one_apm/inst/dispatcher/puma.rb +23 -0
- data/lib/one_apm/inst/dispatcher/rainbows.rb +2 -2
- data/lib/one_apm/inst/framework/grape.rb +4 -4
- data/lib/one_apm/inst/framework/padrino.rb +2 -2
- data/lib/one_apm/inst/framework/sinatra.rb +9 -9
- data/lib/one_apm/inst/framework/sinatra/transaction_namer.rb +1 -1
- data/lib/one_apm/inst/http_clients/curb.rb +6 -6
- data/lib/one_apm/inst/http_clients/excon.rb +4 -4
- data/lib/one_apm/inst/http_clients/excon/middleware.rb +3 -3
- data/lib/one_apm/inst/http_clients/httpclient.rb +1 -1
- data/lib/one_apm/inst/http_clients/net.rb +2 -2
- data/lib/one_apm/inst/http_clients/typhoeus.rb +2 -2
- data/lib/one_apm/inst/nosql/memcache.rb +7 -7
- data/lib/one_apm/inst/nosql/mongo.rb +6 -6
- data/lib/one_apm/inst/nosql/mongo_moped.rb +2 -2
- data/lib/one_apm/inst/nosql/redis.rb +3 -3
- data/lib/one_apm/inst/orm/active_record.rb +4 -4
- data/lib/one_apm/inst/orm/active_record_4.rb +2 -2
- data/lib/one_apm/inst/orm/sequel.rb +4 -4
- data/lib/one_apm/inst/rack.rb +3 -3
- data/lib/one_apm/inst/rack/rack_builder.rb +4 -4
- data/lib/one_apm/inst/rails/action_controller.rb +7 -7
- data/lib/one_apm/inst/rails/action_web_service.rb +1 -1
- data/lib/one_apm/inst/rails/errors.rb +1 -1
- data/lib/one_apm/inst/rails3/action_controller.rb +6 -6
- data/lib/one_apm/inst/rails3/errors.rb +1 -1
- data/lib/one_apm/inst/rails4/action_controller.rb +1 -1
- data/lib/one_apm/inst/rails4/action_controller_subscriber.rb +4 -4
- data/lib/one_apm/inst/rails4/action_view.rb +2 -2
- data/lib/one_apm/inst/rails4/action_view_subscriber.rb +4 -4
- data/lib/one_apm/inst/rails4/active_record_subscriber.rb +7 -7
- data/lib/one_apm/inst/rails4/errors.rb +1 -1
- data/lib/one_apm/inst/rails_middleware.rb +2 -2
- data/lib/one_apm/inst/support/evented_subscriber.rb +2 -2
- data/lib/one_apm/inst/support/queue_time.rb +1 -1
- data/lib/one_apm/inst/transaction_base.rb +6 -6
- data/lib/one_apm/logger/agent_logger.rb +8 -8
- data/lib/one_apm/logger/audit_logger.rb +8 -8
- data/lib/one_apm/logger/memory_logger.rb +1 -1
- data/lib/one_apm/logger/null_logger.rb +1 -3
- data/lib/one_apm/manager.rb +249 -0
- data/lib/one_apm/metrics/metric_spec.rb +1 -1
- data/lib/one_apm/metrics/stats.rb +1 -1
- data/lib/one_apm/probe.rb +1 -1
- data/lib/one_apm/probe/framework_loader.rb +2 -2
- data/lib/one_apm/probe/instance_methods.rb +19 -19
- data/lib/one_apm/probe/instrumentation.rb +5 -5
- data/lib/one_apm/rack/browser_monitoring.rb +6 -6
- data/lib/one_apm/rack/middleware_hooks.rb +1 -1
- data/lib/one_apm/rack/middleware_tracing.rb +2 -2
- data/lib/one_apm/support/chained_call.rb +1 -1
- data/lib/one_apm/support/coerce.rb +1 -1
- data/lib/one_apm/support/collection_helper.rb +1 -1
- data/lib/one_apm/support/encoders.rb +1 -1
- data/lib/one_apm/support/environment_report.rb +10 -10
- data/lib/one_apm/{agent → support}/event/event_listener.rb +3 -3
- data/lib/one_apm/{agent → support}/event/event_loop.rb +8 -8
- data/lib/one_apm/{agent → support}/event/timer.rb +1 -1
- data/lib/one_apm/{agent → support}/event/worker_loop.rb +5 -19
- data/lib/one_apm/{agent/pipe/pipe_channel_manager.rb → support/forked_process_channel.rb} +13 -51
- data/lib/one_apm/support/json_marshaller.rb +6 -6
- data/lib/one_apm/support/json_wrapper.rb +2 -2
- data/lib/one_apm/support/language_support.rb +1 -1
- data/lib/one_apm/support/library_detection.rb +5 -5
- data/lib/one_apm/support/marshaller.rb +1 -1
- data/lib/one_apm/support/method_tracer.rb +12 -12
- data/lib/one_apm/support/method_tracer/helpers.rb +6 -6
- data/lib/one_apm/support/system_info.rb +2 -2
- data/lib/one_apm/support/traced_method_stack.rb +4 -4
- data/lib/one_apm/support/vm/monotonic_gc_profiler.rb +1 -1
- data/lib/one_apm/support/vm/mri_vm.rb +1 -1
- data/lib/one_apm/transaction.rb +3 -3
- data/lib/one_apm/transaction/class_methods.rb +3 -3
- data/lib/one_apm/transaction/instance_helpers.rb +3 -3
- data/lib/one_apm/transaction/sample_buffer/synthetics_sample_buffer.rb +1 -1
- data/lib/one_apm/transaction/sample_buffer/xray_sample_buffer.rb +5 -5
- data/lib/one_apm/transaction/thread_local_access.rb +2 -2
- data/lib/one_apm/transaction/transaction_apdex.rb +2 -2
- data/lib/one_apm/transaction/transaction_finish_append.rb +1 -1
- data/lib/one_apm/transaction/transaction_jruby_functions.rb +2 -2
- data/lib/one_apm/transaction/transaction_name.rb +2 -2
- data/lib/one_apm/transaction/transaction_sample.rb +1 -1
- data/lib/one_apm/transaction/transaction_sample_builder.rb +7 -7
- data/lib/one_apm/transaction/transaction_state.rb +1 -1
- data/lib/one_apm/version.rb +1 -1
- data/lib/sequel/extensions/oneapm_instrumentation.rb +7 -7
- data/oneapm.yml +6 -7
- metadata +10 -9
- data/lib/one_apm/agent/agent.rb +0 -283
@@ -19,7 +19,7 @@ module OneApm
|
|
19
19
|
container_for_endpoint(endpoint).merge!(data)
|
20
20
|
end
|
21
21
|
rescue => e
|
22
|
-
OneApm::
|
22
|
+
OneApm::Manager.logger.error("Error while merging #{endpoint} data from child: ", e)
|
23
23
|
end
|
24
24
|
|
25
25
|
# Clear out the metric data, errors, and transaction traces, etc.
|
@@ -83,27 +83,27 @@ module OneApm
|
|
83
83
|
begin
|
84
84
|
items = container.harvest!
|
85
85
|
rescue => e
|
86
|
-
OneApm::
|
86
|
+
OneApm::Manager.logger.error("Failed to harvest #{endpoint} data, resetting. Error: ", e)
|
87
87
|
container.reset!
|
88
88
|
end
|
89
89
|
items
|
90
90
|
end
|
91
91
|
|
92
92
|
def send_data_to_endpoint(endpoint, items, container)
|
93
|
-
OneApm::
|
93
|
+
OneApm::Manager.logger.debug("Sending #{items.size} items to #{endpoint}")
|
94
94
|
begin
|
95
95
|
@service.send(endpoint, items)
|
96
96
|
rescue ForceRestartException, ForceDisconnectException
|
97
97
|
raise
|
98
98
|
rescue SerializationError => e
|
99
|
-
OneApm::
|
99
|
+
OneApm::Manager.logger.warn("Failed to serialize data for #{endpoint}, discarding. Error: ", e)
|
100
100
|
rescue UnrecoverableServerException => e
|
101
|
-
OneApm::
|
101
|
+
OneApm::Manager.logger.warn("#{endpoint} data was rejected by remote service, discarding. Error: ", e)
|
102
102
|
rescue ServerConnectionException => e
|
103
103
|
log_remote_unavailable(endpoint, e)
|
104
104
|
container.merge!(items)
|
105
105
|
rescue => e
|
106
|
-
OneApm::
|
106
|
+
OneApm::Manager.logger.info("Unable to send #{endpoint} data, will try again later. Error: ", e)
|
107
107
|
container.merge!(items)
|
108
108
|
end
|
109
109
|
end
|
@@ -161,7 +161,7 @@ module OneApm
|
|
161
161
|
now = Time.now
|
162
162
|
|
163
163
|
msg = "Sending #{harvest_method.to_s.gsub("harvest_and_send_", "")} to OneApm Service"
|
164
|
-
|
164
|
+
OneApm::Manager.logger.debug msg
|
165
165
|
|
166
166
|
harvest_lock.synchronize do
|
167
167
|
@service.session do # use http keep-alive
|
@@ -170,13 +170,13 @@ module OneApm
|
|
170
170
|
end
|
171
171
|
ensure
|
172
172
|
duration = (Time.now - now).to_f
|
173
|
-
OneApm::
|
173
|
+
OneApm::Manager.record_metric("Supportability/#{supportability_name}Harvest", duration)
|
174
174
|
end
|
175
175
|
|
176
176
|
# This method is expected to only be called with the harvest_lock already held
|
177
177
|
def transmit_data_already_locked
|
178
178
|
now = Time.now
|
179
|
-
|
179
|
+
OneApm::Manager.logger.debug "Sending data to OneApm Service"
|
180
180
|
|
181
181
|
@events.notify(:before_harvest)
|
182
182
|
@service.session do
|
@@ -191,7 +191,7 @@ module OneApm
|
|
191
191
|
ensure
|
192
192
|
OneApm::Agent::Database.close_connections
|
193
193
|
duration = (Time.now - now).to_f
|
194
|
-
OneApm::
|
194
|
+
OneApm::Manager.record_metric('Supportability/Harvest', duration)
|
195
195
|
end
|
196
196
|
|
197
197
|
def check_for_and_handle_agent_commands
|
@@ -202,14 +202,14 @@ module OneApm
|
|
202
202
|
rescue ServerConnectionException => e
|
203
203
|
log_remote_unavailable(:get_agent_commands, e)
|
204
204
|
rescue => e
|
205
|
-
OneApm::
|
205
|
+
OneApm::Manager.logger.info("Error during check_for_and_handle_agent_commands, will retry later: ", e)
|
206
206
|
end
|
207
207
|
end
|
208
208
|
|
209
209
|
def log_remote_unavailable(endpoint, e)
|
210
|
-
OneApm::
|
211
|
-
OneApm::
|
212
|
-
OneApm::
|
210
|
+
OneApm::Manager.logger.debug("Unable to send #{endpoint} data, will try again later. Error: ", e)
|
211
|
+
OneApm::Manager.record_metric("Supportability/remote_unavailable", 0.0)
|
212
|
+
OneApm::Manager.record_metric("Supportability/remote_unavailable/#{endpoint.to_s}", 0.0)
|
213
213
|
end
|
214
214
|
|
215
215
|
end
|
@@ -3,25 +3,6 @@ module OneApm
|
|
3
3
|
class Agent
|
4
4
|
module ForkableDispatcherFunctions
|
5
5
|
|
6
|
-
# This method should be called in a forked process after a fork.
|
7
|
-
# It assumes the parent process initialized the agent, but does
|
8
|
-
# not assume the agent started.
|
9
|
-
#
|
10
|
-
# The call is idempotent, but not re-entrant.
|
11
|
-
#
|
12
|
-
# * It clears any metrics carried over from the parent process
|
13
|
-
# * Restarts the sampler thread if necessary
|
14
|
-
# * Initiates a new agent run and worker loop unless that was done
|
15
|
-
# in the parent process and +:force_reconnect+ is not true
|
16
|
-
#
|
17
|
-
# Options:
|
18
|
-
# * <tt>:force_reconnect => true</tt> to force the spawned process to
|
19
|
-
# establish a new connection, such as when forking a long running process.
|
20
|
-
# The default is false--it will only connect to the server if the parent
|
21
|
-
# had not connected.
|
22
|
-
# * <tt>:keep_retrying => false</tt> if we try to initiate a new
|
23
|
-
# connection, this tells me to only try it once so this method returns
|
24
|
-
# quickly if there is some kind of latency with the server.
|
25
6
|
def after_fork(options={})
|
26
7
|
needs_restart = false
|
27
8
|
@after_fork_lock.synchronize do
|
@@ -30,16 +11,15 @@ module OneApm
|
|
30
11
|
end
|
31
12
|
|
32
13
|
return if !needs_restart ||
|
33
|
-
!
|
34
|
-
!
|
14
|
+
!Manager.config[:agent_enabled] ||
|
15
|
+
!Manager.config[:monitor_mode] ||
|
35
16
|
disconnected?
|
36
17
|
|
37
|
-
|
18
|
+
OneApm::Manager.logger.debug "Starting the worker thread in #{Process.pid} (parent #{Process.ppid}) after forking."
|
38
19
|
|
39
20
|
channel_id = options[:report_to_channel]
|
40
21
|
install_pipe_service(channel_id) if channel_id
|
41
22
|
|
42
|
-
# Clear out locks and stats left over from parent process
|
43
23
|
reset_objects_with_locks
|
44
24
|
drop_buffered_data
|
45
25
|
|
@@ -47,36 +27,27 @@ module OneApm
|
|
47
27
|
end
|
48
28
|
|
49
29
|
def install_pipe_service(channel_id)
|
50
|
-
@service = OneApm::Agent::
|
30
|
+
@service = OneApm::Agent::ForkedProcessService.new(channel_id)
|
51
31
|
if connected?
|
52
32
|
@connected_pid = Process.pid
|
53
33
|
else
|
54
|
-
|
34
|
+
OneApm::Manager.logger.debug("Child process #{Process.pid} not reporting to non-connected parent (process #{Process.ppid}).")
|
55
35
|
@service.shutdown(Time.now)
|
56
36
|
disconnect
|
57
37
|
end
|
58
38
|
end
|
59
39
|
|
60
|
-
# Synchronize with the harvest loop. If the harvest thread has taken
|
61
|
-
# a lock (DNS lookups, backticks, agent-owned locks, etc), and we
|
62
|
-
# fork while locked, this can deadlock child processes. For more
|
63
|
-
# details, see https://github.com/resque/resque/issues/1101
|
64
40
|
def synchronize_with_harvest
|
65
41
|
harvest_lock.synchronize do
|
66
42
|
yield
|
67
43
|
end
|
68
44
|
end
|
69
45
|
|
70
|
-
# Clear out state for any objects that we know lock from our parents
|
71
|
-
# This is necessary for cases where we're in a forked child and Ruby
|
72
|
-
# might be holding locks for background thread that aren't there anymore.
|
73
46
|
def reset_objects_with_locks
|
74
47
|
@stats_engine = OneApm::Collector::StatsEngine.new
|
75
48
|
reset_harvest_locks
|
76
49
|
end
|
77
50
|
|
78
|
-
# Some forking cases (like Resque) end up with harvest lock from the
|
79
|
-
# parent process orphaned in the child. Let it go before we proceed.
|
80
51
|
def reset_harvest_locks
|
81
52
|
return if harvest_lock.nil?
|
82
53
|
|
@@ -84,7 +55,7 @@ module OneApm
|
|
84
55
|
end
|
85
56
|
|
86
57
|
def flush_pipe_data
|
87
|
-
if connected? && @service.is_a?(::OneApm::Agent::
|
58
|
+
if connected? && @service.is_a?(::OneApm::Agent::ForkedProcessService)
|
88
59
|
transmit_data
|
89
60
|
transmit_event_data
|
90
61
|
end
|
@@ -6,40 +6,29 @@ module OneApm
|
|
6
6
|
def obfuscator
|
7
7
|
@obfuscator ||= lambda {|sql| OneApm::Agent::Database.default_sql_obfuscator(sql) }
|
8
8
|
end
|
9
|
-
|
10
|
-
|
11
|
-
# previous value, if there is one
|
12
|
-
def set_record_sql(should_record) #THREAD_LOCAL_ACCESS
|
9
|
+
|
10
|
+
def set_record_sql(should_record)
|
13
11
|
state = TransactionState.tl_get
|
14
12
|
prev = state.record_sql
|
15
13
|
state.record_sql = should_record
|
16
14
|
prev.nil? || prev
|
17
15
|
end
|
18
16
|
|
19
|
-
|
20
|
-
# should not record transaction traces in the current
|
21
|
-
# thread. Returns the previous value, if there is one
|
22
|
-
def set_record_tt(should_record) #THREAD_LOCAL_ACCESS
|
17
|
+
def set_record_tt(should_record)
|
23
18
|
state = TransactionState.tl_get
|
24
19
|
prev = state.record_tt
|
25
20
|
state.record_tt = should_record
|
26
21
|
prev.nil? || prev
|
27
22
|
end
|
28
23
|
|
29
|
-
|
30
|
-
# thread. This uses a stack which allows us to disable tracing
|
31
|
-
# children of a transaction without affecting the tracing of
|
32
|
-
# the whole transaction
|
33
|
-
def push_trace_execution_flag(should_trace=false) #THREAD_LOCAL_ACCESS
|
24
|
+
def push_trace_execution_flag(should_trace=false)
|
34
25
|
TransactionState.tl_get.push_traced(should_trace)
|
35
26
|
end
|
36
27
|
|
37
|
-
|
38
|
-
# to what it was before we pushed the current flag.
|
39
|
-
def pop_trace_execution_flag #THREAD_LOCAL_ACCESS
|
28
|
+
def pop_trace_execution_flag
|
40
29
|
TransactionState.tl_get.pop_traced
|
41
30
|
end
|
42
31
|
end
|
43
32
|
end
|
44
33
|
end
|
45
|
-
end
|
34
|
+
end
|
@@ -25,10 +25,10 @@ module OneApm
|
|
25
25
|
unless in_resque_child_process?
|
26
26
|
generate_environment_report
|
27
27
|
install_exit_handler
|
28
|
-
@harvest_samplers.load_samplers unless
|
28
|
+
@harvest_samplers.load_samplers unless OneApm::Manager.config[:disable_samplers]
|
29
29
|
end
|
30
30
|
|
31
|
-
connect_in_foreground if
|
31
|
+
connect_in_foreground if OneApm::Manager.config[:sync_startup]
|
32
32
|
start_worker_thread(options)
|
33
33
|
end
|
34
34
|
|
@@ -40,7 +40,7 @@ module OneApm
|
|
40
40
|
# Check whether we have already started, which is an error condition
|
41
41
|
def already_started?
|
42
42
|
if started?
|
43
|
-
|
43
|
+
OneApm::Manager.logger.error("Agent Started Already!")
|
44
44
|
true
|
45
45
|
end
|
46
46
|
end
|
@@ -49,7 +49,7 @@ module OneApm
|
|
49
49
|
# behavior of at_exit blocks to make sure it runs last, by
|
50
50
|
# doing an at_exit within an at_exit block.
|
51
51
|
def install_exit_handler
|
52
|
-
if
|
52
|
+
if OneApm::Manager.config[:send_data_on_exit] && !weird_ruby?
|
53
53
|
at_exit do
|
54
54
|
# Workaround for MRI 1.9 bug that loses exit codes in at_exit blocks.
|
55
55
|
# This is necessary to get correct exit codes for the agent's
|
@@ -70,12 +70,12 @@ module OneApm
|
|
70
70
|
# 'agent_enabled' option (e.g. in a manual start), or
|
71
71
|
# enabled normally through the configuration file
|
72
72
|
def disabled?
|
73
|
-
!
|
73
|
+
!Manager.config[:agent_enabled]
|
74
74
|
end
|
75
75
|
|
76
76
|
# Logs the configured application names
|
77
77
|
def app_name_configured?
|
78
|
-
names =
|
78
|
+
names = OneApm::Manager.config.app_names
|
79
79
|
return names.respond_to?(:any?) && names.any?
|
80
80
|
end
|
81
81
|
|
@@ -85,7 +85,7 @@ module OneApm
|
|
85
85
|
# to get statistics from before a server connection
|
86
86
|
# (typically 20 seconds) exists
|
87
87
|
def connect_in_foreground
|
88
|
-
OneApm::
|
88
|
+
OneApm::Manager.disable_all_tracing { connect(:keep_retrying => false) }
|
89
89
|
end
|
90
90
|
|
91
91
|
# If we're using sinatra, old versions run in an at_exit
|
@@ -105,10 +105,10 @@ module OneApm
|
|
105
105
|
# Warn the user if they have configured their agent not to
|
106
106
|
# send data, that way we can see this clearly in the log file
|
107
107
|
def monitoring?
|
108
|
-
if
|
108
|
+
if OneApm::Manager.config[:monitor_mode]
|
109
109
|
true
|
110
110
|
else
|
111
|
-
|
111
|
+
OneApm::Manager.logger.warn('Agent configured not to send data in this environment.')
|
112
112
|
false
|
113
113
|
end
|
114
114
|
end
|
@@ -116,10 +116,10 @@ module OneApm
|
|
116
116
|
# Tell the user when the license key is missing so they can
|
117
117
|
# fix it by adding it to the file
|
118
118
|
def has_license_key?
|
119
|
-
if
|
119
|
+
if OneApm::Manager.config[:license_key] && OneApm::Manager.config[:license_key].length > 0
|
120
120
|
true
|
121
121
|
else
|
122
|
-
|
122
|
+
OneApm::Manager.logger.warn("No license key found. " +
|
123
123
|
"This often means your oneapm.yml file was not found, or it lacks a section for the running environment, '#{OneApm::Probe.instance.env}'. You may also want to try linting your oneapm.yml to ensure it is valid YML.")
|
124
124
|
false
|
125
125
|
end
|
@@ -134,8 +134,8 @@ module OneApm
|
|
134
134
|
# requests, we need to wait until the children are forked
|
135
135
|
# before connecting, otherwise the parent process sends useless data
|
136
136
|
def using_forking_dispatcher?
|
137
|
-
if [:puma, :passenger, :rainbows, :unicorn].include?
|
138
|
-
|
137
|
+
if [:puma, :passenger, :rainbows, :unicorn].include? OneApm::Manager.config[:dispatcher]
|
138
|
+
OneApm::Manager.logger.info "Deferring startup of agent reporting thread because #{Manager.config[:dispatcher]} may fork."
|
139
139
|
true
|
140
140
|
else
|
141
141
|
false
|
@@ -144,12 +144,12 @@ module OneApm
|
|
144
144
|
|
145
145
|
def defer_for_background_jobs?
|
146
146
|
if defer_for_delayed_job?
|
147
|
-
|
147
|
+
OneApm::Manager.logger.debug "Deferring startup for DelayedJob"
|
148
148
|
return true
|
149
149
|
end
|
150
150
|
|
151
151
|
if defer_for_resque?
|
152
|
-
|
152
|
+
OneApm::Manager.logger.debug "Deferring startup for Resque in case it daemonizes"
|
153
153
|
return true
|
154
154
|
end
|
155
155
|
|
@@ -159,7 +159,7 @@ module OneApm
|
|
159
159
|
require 'one_apm/inst/background_job/delayed_job_injection'
|
160
160
|
|
161
161
|
def defer_for_delayed_job?
|
162
|
-
OneApm::
|
162
|
+
OneApm::Manager.config[:dispatcher] == :delayed_job &&
|
163
163
|
!OneApm::DelayedJobInjection.worker_name
|
164
164
|
end
|
165
165
|
|
@@ -167,13 +167,13 @@ module OneApm
|
|
167
167
|
# daemonize itself. This avoids hanging when there's a Thread started
|
168
168
|
# before Resque calls Process.daemon (Jira RUBY-857)
|
169
169
|
def defer_for_resque?
|
170
|
-
OneApm::
|
170
|
+
OneApm::Manager.config[:dispatcher] == :resque &&
|
171
171
|
OneApm::LanguageSupport.can_fork? &&
|
172
|
-
!OneApm::
|
172
|
+
!OneApm::Support::ForkedProcessChannel.listener.started?
|
173
173
|
end
|
174
174
|
|
175
175
|
def in_resque_child_process?
|
176
|
-
@service.is_a?(OneApm::Agent::
|
176
|
+
@service.is_a?(OneApm::Agent::ForkedProcessService)
|
177
177
|
end
|
178
178
|
|
179
179
|
# Log startup information that we almost always want to know
|
@@ -187,37 +187,37 @@ module OneApm
|
|
187
187
|
# so we can disambiguate processes in the log file and make
|
188
188
|
# sure they're running a reasonable version
|
189
189
|
def log_version_and_pid
|
190
|
-
|
190
|
+
OneApm::Manager.logger.debug "OneApm Ruby Agent #{OneApm::VERSION::STRING} Initialized: pid = #{$$}"
|
191
191
|
end
|
192
192
|
|
193
193
|
# Log the environment the app thinks it's running in.
|
194
194
|
# Useful in debugging, as this is the key for config YAML lookups.
|
195
195
|
def log_environment
|
196
|
-
|
196
|
+
OneApm::Manager.logger.info "Environment: #{OneApm::Probe.instance.env}"
|
197
197
|
end
|
198
198
|
|
199
199
|
# Logs the dispatcher to the log file to assist with
|
200
200
|
# debugging. When no debugger is present, logs this fact to
|
201
201
|
# assist with proper dispatcher detection
|
202
202
|
def log_dispatcher
|
203
|
-
dispatcher_name =
|
203
|
+
dispatcher_name = OneApm::Manager.config[:dispatcher].to_s
|
204
204
|
|
205
205
|
if dispatcher_name.empty?
|
206
|
-
|
206
|
+
OneApm::Manager.logger.info 'No known dispatcher detected.'
|
207
207
|
else
|
208
|
-
|
208
|
+
OneApm::Manager.logger.info "Dispatcher: #{dispatcher_name}"
|
209
209
|
end
|
210
210
|
end
|
211
211
|
|
212
212
|
def log_app_name
|
213
|
-
|
213
|
+
OneApm::Manager.logger.info "Application: #{Manager.config.app_names.join(", ")}"
|
214
214
|
end
|
215
215
|
|
216
216
|
def log_ignore_url_regexes
|
217
|
-
regexes = OneApm::
|
217
|
+
regexes = OneApm::Manager.config[:'rules.ignore_url_regexes']
|
218
218
|
|
219
219
|
unless regexes.empty?
|
220
|
-
|
220
|
+
OneApm::Manager.logger.info "Ignoring URLs that match the following regexes: #{regexes.map(&:inspect).join(", ")}."
|
221
221
|
end
|
222
222
|
end
|
223
223
|
end
|
@@ -1,50 +1,32 @@
|
|
1
1
|
module OneApm
|
2
2
|
module Agent
|
3
3
|
class Agent
|
4
|
-
# All of this module used to be contained in the
|
5
|
-
# start_worker_thread method - this is an artifact of
|
6
|
-
# refactoring and can be moved, renamed, etc at will
|
7
4
|
module StartWorkerThread
|
8
5
|
|
9
|
-
# Never allow any data type to be reported more frequently than once
|
10
|
-
# per second.
|
11
6
|
MIN_ALLOWED_REPORT_PERIOD = 1.0
|
12
|
-
UTILIZATION_REPORT_PERIOD = 30 * 60
|
7
|
+
UTILIZATION_REPORT_PERIOD = 30 * 60
|
13
8
|
LOG_ONCE_KEYS_RESET_PERIOD = 60.0
|
14
9
|
|
15
|
-
# Try to launch the worker thread and connect to the server.
|
16
|
-
#
|
17
|
-
# See #connect for a description of connection_options.
|
18
10
|
def start_worker_thread(connection_options = {})
|
19
|
-
if disable = OneApm::
|
20
|
-
OneApm::
|
11
|
+
if disable = OneApm::Manager.config[:disable_harvest_thread]
|
12
|
+
OneApm::Manager.logger.info "Not starting Ruby Agent worker thread because :disable_harvest_thread is #{disable}"
|
21
13
|
return
|
22
14
|
end
|
23
15
|
|
24
|
-
|
16
|
+
OneApm::Manager.logger.debug "Creating Ruby Agent worker thread."
|
25
17
|
@worker_thread = OneApm::Agent::Threading::AgentThread.create('Worker Loop') do
|
26
18
|
deferred_work!(connection_options)
|
27
19
|
end
|
28
20
|
end
|
29
21
|
|
30
|
-
# This is the method that is run in a new thread in order to
|
31
|
-
# background the harvesting and sending of data during the
|
32
|
-
# normal operation of the agent.
|
33
|
-
#
|
34
|
-
# Takes connection options that determine how we should
|
35
|
-
# connect to the server, and loops endlessly - typically we
|
36
|
-
# never return from this method unless we're shutting down
|
37
|
-
# the agent
|
38
22
|
def deferred_work!(connection_options)
|
39
23
|
catch_errors do
|
40
|
-
OneApm::
|
24
|
+
OneApm::Manager.disable_all_tracing do
|
41
25
|
connect(connection_options)
|
42
26
|
if connected?
|
43
27
|
create_and_run_event_loop
|
44
|
-
# never reaches here unless there is a problem or
|
45
|
-
# the agent is exiting
|
46
28
|
else
|
47
|
-
|
29
|
+
OneApm::Manager.logger.debug "No connection. Worker thread ending."
|
48
30
|
end
|
49
31
|
end
|
50
32
|
end
|
@@ -55,13 +37,13 @@ module OneApm
|
|
55
37
|
|
56
38
|
@event_loop.on(:report_data) { transmit_data }
|
57
39
|
@event_loop.on(:report_event_data) { transmit_event_data }
|
58
|
-
@event_loop.on(:reset_log_once_keys) { OneApm::
|
40
|
+
@event_loop.on(:reset_log_once_keys) { OneApm::Manager.logger.clear_already_logged }
|
59
41
|
|
60
|
-
@event_loop.fire_every(
|
42
|
+
@event_loop.fire_every(Manager.config[:data_report_period], :report_data)
|
61
43
|
@event_loop.fire_every(report_period_for(:analytic_event_data), :report_event_data)
|
62
44
|
@event_loop.fire_every(LOG_ONCE_KEYS_RESET_PERIOD, :reset_log_once_keys)
|
63
45
|
|
64
|
-
if
|
46
|
+
if OneApm::Manager.config[:collect_utilization] && !in_resque_child_process?
|
65
47
|
@event_loop.on(:report_utilization_data) { transmit_utilization_data }
|
66
48
|
|
67
49
|
@event_loop.fire(:report_utilization_data)
|
@@ -72,18 +54,18 @@ module OneApm
|
|
72
54
|
end
|
73
55
|
|
74
56
|
def create_event_loop
|
75
|
-
EventLoop.new
|
57
|
+
OneApm::Support::EventLoop.new
|
76
58
|
end
|
77
59
|
|
78
60
|
def report_period_for(method)
|
79
61
|
config_key = "data_report_periods.#{method}".to_sym
|
80
|
-
period =
|
62
|
+
period = OneApm::Manager.config[config_key]
|
81
63
|
if !period
|
82
|
-
period =
|
83
|
-
|
64
|
+
period = OneApm::Manager.config[:data_report_period]
|
65
|
+
OneApm::Manager.logger.warn("Could not find configured period for #{method}, falling back to data_report_period (#{period} s)")
|
84
66
|
end
|
85
67
|
if period < MIN_ALLOWED_REPORT_PERIOD
|
86
|
-
|
68
|
+
OneApm::Manager.logger.warn("Configured #{config_key} was #{period}, but minimum allowed is #{MIN_ALLOWED_REPORT_PERIOD}, using #{MIN_ALLOWED_REPORT_PERIOD}.")
|
87
69
|
period = MIN_ALLOWED_REPORT_PERIOD
|
88
70
|
end
|
89
71
|
period
|
@@ -91,16 +73,13 @@ module OneApm
|
|
91
73
|
|
92
74
|
def stop_event_loop
|
93
75
|
if @event_loop
|
94
|
-
@event_loop.run_once(true) if
|
76
|
+
@event_loop.run_once(true) if OneApm::Manager.config[:force_send]
|
95
77
|
@event_loop.stop
|
96
78
|
end
|
97
79
|
end
|
98
80
|
|
99
81
|
private
|
100
82
|
|
101
|
-
# a wrapper method to handle all the errors that can happen
|
102
|
-
# in the connection and worker thread system. This
|
103
|
-
# guarantees a no-throw from the background thread.
|
104
83
|
def catch_errors
|
105
84
|
yield
|
106
85
|
rescue OneApm::ForceRestartException => e
|
@@ -112,33 +91,22 @@ module OneApm
|
|
112
91
|
handle_other_error(e)
|
113
92
|
end
|
114
93
|
|
115
|
-
# Handles the case where the server tells us to restart -
|
116
|
-
# this clears the data, clears connection attempts, and
|
117
|
-
# waits a while to reconnect.
|
118
94
|
def handle_force_restart(error)
|
119
|
-
|
95
|
+
OneApm::Manager.logger.debug error.message
|
120
96
|
drop_buffered_data
|
121
97
|
@service.reset_metric_id_cache if @service
|
122
98
|
@connect_state = :pending
|
123
99
|
sleep 30
|
124
100
|
end
|
125
101
|
|
126
|
-
# when a disconnect is requested, stop the current thread, which
|
127
|
-
# is the worker thread that gathers data and talks to the
|
128
|
-
# server.
|
129
102
|
def handle_force_disconnect(error)
|
130
|
-
|
103
|
+
OneApm::Manager.logger.warn "OneApm forced this agent to disconnect (#{error.message})"
|
131
104
|
disconnect
|
132
105
|
end
|
133
106
|
|
134
|
-
# Handles an unknown error in the worker thread by logging
|
135
|
-
# it and disconnecting the agent, since we are now in an
|
136
|
-
# unknown state.
|
137
107
|
def handle_other_error(error)
|
138
|
-
|
139
|
-
|
140
|
-
# reporting entirely), so we really want backtraces when they happen
|
141
|
-
::OneApm::Agent.logger.log_exception(:error, error)
|
108
|
+
OneApm::Manager.logger.error "Unhandled error in worker thread, disconnecting this agent process:"
|
109
|
+
OneApm::Manager.logger.log_exception(:error, error)
|
142
110
|
disconnect
|
143
111
|
end
|
144
112
|
|