oneapm_rpm 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +30 -0
- data/.rubocop.yml +725 -0
- data/Gemfile +3 -0
- data/Guardfile +7 -0
- data/LICENSE +1 -0
- data/README.md +3 -0
- data/config/cert/cacert.pem +1177 -0
- data/config/database.yml +5 -0
- data/lib/initializers/goliath.rb +11 -0
- data/lib/initializers/other.rb +1 -0
- data/lib/initializers/rails.rb +15 -0
- data/lib/one_apm/agent.rb +253 -0
- data/lib/one_apm/agent/agent.rb +283 -0
- data/lib/one_apm/agent/agent/connect.rb +175 -0
- data/lib/one_apm/agent/agent/container_data_manager.rb +218 -0
- data/lib/one_apm/agent/agent/forkable_dispatcher_functions.rb +96 -0
- data/lib/one_apm/agent/agent/helpers.rb +45 -0
- data/lib/one_apm/agent/agent/start.rb +226 -0
- data/lib/one_apm/agent/agent/start_worker_thread.rb +148 -0
- data/lib/one_apm/agent/busy_calculator.rb +115 -0
- data/lib/one_apm/agent/cross_app/cross_app_monitor.rb +181 -0
- data/lib/one_apm/agent/cross_app/cross_app_tracing.rb +336 -0
- data/lib/one_apm/agent/database.rb +308 -0
- data/lib/one_apm/agent/database/active_record_helper.rb +80 -0
- data/lib/one_apm/agent/database/obfuscation_helpers.rb +76 -0
- data/lib/one_apm/agent/database/obfuscator.rb +78 -0
- data/lib/one_apm/agent/database/postgres_explain_obfuscator.rb +45 -0
- data/lib/one_apm/agent/datastores.rb +175 -0
- data/lib/one_apm/agent/datastores/metric_helper.rb +83 -0
- data/lib/one_apm/agent/datastores/mongo.rb +27 -0
- data/lib/one_apm/agent/datastores/mongo/metric_translator.rb +189 -0
- data/lib/one_apm/agent/datastores/mongo/obfuscator.rb +37 -0
- data/lib/one_apm/agent/datastores/mongo/statement_formatter.rb +51 -0
- data/lib/one_apm/agent/event/event_listener.rb +40 -0
- data/lib/one_apm/agent/event/event_loop.rb +191 -0
- data/lib/one_apm/agent/event/worker_loop.rb +97 -0
- data/lib/one_apm/agent/harvester.rb +48 -0
- data/lib/one_apm/agent/inbound_request_monitor.rb +30 -0
- data/lib/one_apm/agent/javascript_instrumentor.rb +186 -0
- data/lib/one_apm/agent/pipe/pipe_channel_manager.rb +275 -0
- data/lib/one_apm/agent/pipe/pipe_service.rb +81 -0
- data/lib/one_apm/agent/sampler.rb +55 -0
- data/lib/one_apm/agent/sampler_collection.rb +65 -0
- data/lib/one_apm/agent/samplers/cpu_sampler.rb +49 -0
- data/lib/one_apm/agent/samplers/delayed_job_sampler.rb +109 -0
- data/lib/one_apm/agent/samplers/memory_sampler.rb +144 -0
- data/lib/one_apm/agent/samplers/object_sampler.rb +22 -0
- data/lib/one_apm/agent/samplers/vm_sampler.rb +124 -0
- data/lib/one_apm/agent/synthetics_monitor.rb +48 -0
- data/lib/one_apm/agent/threading/agent_thread.rb +74 -0
- data/lib/one_apm/agent/threading/backtrace_node.rb +133 -0
- data/lib/one_apm/agent/threading/backtrace_service.rb +259 -0
- data/lib/one_apm/agent/threading/thread_profile.rb +155 -0
- data/lib/one_apm/collector/collector/helper.rb +139 -0
- data/lib/one_apm/collector/collector/http_connection.rb +254 -0
- data/lib/one_apm/collector/collector/server_methods.rb +71 -0
- data/lib/one_apm/collector/collector_service.rb +123 -0
- data/lib/one_apm/collector/commands/agent_command.rb +17 -0
- data/lib/one_apm/collector/commands/thread_profiler_session.rb +108 -0
- data/lib/one_apm/collector/commands/xray_session.rb +53 -0
- data/lib/one_apm/collector/commands/xray_session_collection.rb +156 -0
- data/lib/one_apm/collector/containers/agent_command_router.rb +153 -0
- data/lib/one_apm/collector/containers/custom_event_aggregator.rb +94 -0
- data/lib/one_apm/collector/containers/error_collector.rb +349 -0
- data/lib/one_apm/collector/containers/sql_sampler.rb +331 -0
- data/lib/one_apm/collector/containers/stats_engine.rb +34 -0
- data/lib/one_apm/collector/containers/transaction_event_aggregator.rb +249 -0
- data/lib/one_apm/collector/containers/transaction_sampler.rb +352 -0
- data/lib/one_apm/collector/containers/utilization_data.rb +36 -0
- data/lib/one_apm/collector/stats_engine/gc_profiler.rb +106 -0
- data/lib/one_apm/collector/stats_engine/metric_stats.rb +243 -0
- data/lib/one_apm/collector/stats_engine/stats_hash.rb +105 -0
- data/lib/one_apm/configuration.rb +429 -0
- data/lib/one_apm/configuration/autostart.rb +41 -0
- data/lib/one_apm/configuration/default_source.rb +1026 -0
- data/lib/one_apm/configuration/environment_source.rb +113 -0
- data/lib/one_apm/configuration/high_security_source.rb +56 -0
- data/lib/one_apm/configuration/manual_source.rb +13 -0
- data/lib/one_apm/configuration/server_source.rb +60 -0
- data/lib/one_apm/configuration/yaml_source.rb +134 -0
- data/lib/one_apm/errors/agent_errors.rb +26 -0
- data/lib/one_apm/errors/internal_agent_error.rb +16 -0
- data/lib/one_apm/errors/noticed_error.rb +79 -0
- data/lib/one_apm/frameworks/external.rb +15 -0
- data/lib/one_apm/frameworks/rails.rb +103 -0
- data/lib/one_apm/frameworks/rails3.rb +37 -0
- data/lib/one_apm/frameworks/rails4.rb +21 -0
- data/lib/one_apm/frameworks/ruby.rb +21 -0
- data/lib/one_apm/frameworks/sinatra.rb +12 -0
- data/lib/one_apm/inst/3rd/active_merchant.rb +35 -0
- data/lib/one_apm/inst/3rd/acts_as_solr.rb +70 -0
- data/lib/one_apm/inst/3rd/authlogic.rb +23 -0
- data/lib/one_apm/inst/3rd/sunspot.rb +31 -0
- data/lib/one_apm/inst/background_job/active_job.rb +88 -0
- data/lib/one_apm/inst/background_job/delayed_job.rb +52 -0
- data/lib/one_apm/inst/background_job/delayed_job_injection.rb +8 -0
- data/lib/one_apm/inst/background_job/resque.rb +107 -0
- data/lib/one_apm/inst/background_job/sidekiq.rb +64 -0
- data/lib/one_apm/inst/dispatcher/passenger.rb +25 -0
- data/lib/one_apm/inst/dispatcher/rainbows.rb +23 -0
- data/lib/one_apm/inst/framework/grape.rb +94 -0
- data/lib/one_apm/inst/framework/padrino.rb +30 -0
- data/lib/one_apm/inst/framework/sinatra.rb +185 -0
- data/lib/one_apm/inst/framework/sinatra/ignorer.rb +50 -0
- data/lib/one_apm/inst/framework/sinatra/transaction_namer.rb +54 -0
- data/lib/one_apm/inst/http_clients/curb.rb +189 -0
- data/lib/one_apm/inst/http_clients/excon.rb +70 -0
- data/lib/one_apm/inst/http_clients/excon/connection.rb +31 -0
- data/lib/one_apm/inst/http_clients/excon/middleware.rb +55 -0
- data/lib/one_apm/inst/http_clients/httpclient.rb +44 -0
- data/lib/one_apm/inst/http_clients/net.rb +34 -0
- data/lib/one_apm/inst/http_clients/typhoeus.rb +76 -0
- data/lib/one_apm/inst/nosql/memcache.rb +134 -0
- data/lib/one_apm/inst/nosql/mongo.rb +126 -0
- data/lib/one_apm/inst/nosql/mongo_moped.rb +85 -0
- data/lib/one_apm/inst/nosql/redis.rb +83 -0
- data/lib/one_apm/inst/orm/active_record.rb +99 -0
- data/lib/one_apm/inst/orm/active_record_4.rb +28 -0
- data/lib/one_apm/inst/orm/data_mapper.rb +180 -0
- data/lib/one_apm/inst/orm/sequel.rb +47 -0
- data/lib/one_apm/inst/rack.rb +38 -0
- data/lib/one_apm/inst/rack/rack.rb +44 -0
- data/lib/one_apm/inst/rack/rack_builder.rb +51 -0
- data/lib/one_apm/inst/rails/action_controller.rb +118 -0
- data/lib/one_apm/inst/rails/action_web_service.rb +44 -0
- data/lib/one_apm/inst/rails/errors.rb +43 -0
- data/lib/one_apm/inst/rails3/action_controller.rb +172 -0
- data/lib/one_apm/inst/rails3/errors.rb +43 -0
- data/lib/one_apm/inst/rails4/action_controller.rb +27 -0
- data/lib/one_apm/inst/rails4/action_controller_subscriber.rb +121 -0
- data/lib/one_apm/inst/rails4/action_view.rb +23 -0
- data/lib/one_apm/inst/rails4/action_view_subscriber.rb +93 -0
- data/lib/one_apm/inst/rails4/active_record_subscriber.rb +96 -0
- data/lib/one_apm/inst/rails4/errors.rb +42 -0
- data/lib/one_apm/inst/rails_middleware.rb +40 -0
- data/lib/one_apm/inst/support/evented_subscriber.rb +98 -0
- data/lib/one_apm/inst/support/ignore_actions.rb +39 -0
- data/lib/one_apm/inst/support/queue_time.rb +76 -0
- data/lib/one_apm/inst/transaction_base.rb +405 -0
- data/lib/one_apm/logger/agent_logger.rb +206 -0
- data/lib/one_apm/logger/audit_logger.rb +78 -0
- data/lib/one_apm/logger/memory_logger.rb +50 -0
- data/lib/one_apm/logger/null_logger.rb +19 -0
- data/lib/one_apm/metrics/metric_data.rb +72 -0
- data/lib/one_apm/metrics/metric_spec.rb +82 -0
- data/lib/one_apm/metrics/stats.rb +173 -0
- data/lib/one_apm/probe.rb +16 -0
- data/lib/one_apm/probe/framework_loader.rb +53 -0
- data/lib/one_apm/probe/instance_methods.rb +105 -0
- data/lib/one_apm/probe/instrumentation.rb +60 -0
- data/lib/one_apm/rack/browser_monitoring.rb +144 -0
- data/lib/one_apm/rack/middleware_base.rb +27 -0
- data/lib/one_apm/rack/middleware_hooks.rb +17 -0
- data/lib/one_apm/rack/middleware_tracing.rb +81 -0
- data/lib/one_apm/rack/middleware_wrapper.rb +86 -0
- data/lib/one_apm/support/chained_call.rb +15 -0
- data/lib/one_apm/support/coerce.rb +81 -0
- data/lib/one_apm/support/collection_helper.rb +79 -0
- data/lib/one_apm/support/dotted_hash.rb +45 -0
- data/lib/one_apm/support/encoders.rb +34 -0
- data/lib/one_apm/support/environment_report.rb +127 -0
- data/lib/one_apm/support/event_buffer.rb +82 -0
- data/lib/one_apm/support/event_buffer/sampled_buffer.rb +45 -0
- data/lib/one_apm/support/event_buffer/sized_buffer.rb +21 -0
- data/lib/one_apm/support/event_buffer/synthetics_event_buffer.rb +40 -0
- data/lib/one_apm/support/helper.rb +49 -0
- data/lib/one_apm/support/hostname.rb +13 -0
- data/lib/one_apm/support/http_clients/curb_wrappers.rb +65 -0
- data/lib/one_apm/support/http_clients/excon_wrappers.rb +63 -0
- data/lib/one_apm/support/http_clients/httpclient_wrappers.rb +61 -0
- data/lib/one_apm/support/http_clients/net_http_wrappers.rb +48 -0
- data/lib/one_apm/support/http_clients/typhoeus_wrappers.rb +73 -0
- data/lib/one_apm/support/http_clients/uri_util.rb +39 -0
- data/lib/one_apm/support/json_marshaller.rb +68 -0
- data/lib/one_apm/support/json_wrapper.rb +130 -0
- data/lib/one_apm/support/language_support.rb +142 -0
- data/lib/one_apm/support/library_detection.rb +119 -0
- data/lib/one_apm/support/local_environment.rb +196 -0
- data/lib/one_apm/support/marshaller.rb +62 -0
- data/lib/one_apm/support/method_tracer.rb +334 -0
- data/lib/one_apm/support/method_tracer/helpers.rb +92 -0
- data/lib/one_apm/support/method_tracer/traced_method_stack.rb +103 -0
- data/lib/one_apm/support/obfuscator.rb +47 -0
- data/lib/one_apm/support/okjson.rb +601 -0
- data/lib/one_apm/support/parameter_filtering.rb +35 -0
- data/lib/one_apm/support/rules_engine.rb +56 -0
- data/lib/one_apm/support/rules_engine/replacement_rule.rb +80 -0
- data/lib/one_apm/support/rules_engine/segment_terms_rule.rb +46 -0
- data/lib/one_apm/support/server.rb +11 -0
- data/lib/one_apm/support/supported_versions.rb +257 -0
- data/lib/one_apm/support/system_info.rb +211 -0
- data/lib/one_apm/support/timer_lib.rb +29 -0
- data/lib/one_apm/support/version_number.rb +51 -0
- data/lib/one_apm/support/vm.rb +30 -0
- data/lib/one_apm/support/vm/jruby_vm.rb +38 -0
- data/lib/one_apm/support/vm/monotonic_gc_profiler.rb +43 -0
- data/lib/one_apm/support/vm/mri_vm.rb +85 -0
- data/lib/one_apm/support/vm/rubinius_vm.rb +129 -0
- data/lib/one_apm/support/vm/snapshot.rb +18 -0
- data/lib/one_apm/transaction.rb +336 -0
- data/lib/one_apm/transaction/class_methods.rb +132 -0
- data/lib/one_apm/transaction/instance_helpers.rb +82 -0
- data/lib/one_apm/transaction/metric_constants.rb +42 -0
- data/lib/one_apm/transaction/sample_buffer/force_persist_sample_buffer.rb +21 -0
- data/lib/one_apm/transaction/sample_buffer/slowest_sample_buffer.rb +21 -0
- data/lib/one_apm/transaction/sample_buffer/synthetics_sample_buffer.rb +21 -0
- data/lib/one_apm/transaction/sample_buffer/transaction_sample_buffer.rb +101 -0
- data/lib/one_apm/transaction/sample_buffer/xray_sample_buffer.rb +60 -0
- data/lib/one_apm/transaction/segment.rb +193 -0
- data/lib/one_apm/transaction/segment_summary.rb +51 -0
- data/lib/one_apm/transaction/thread_local_access.rb +73 -0
- data/lib/one_apm/transaction/transaction_analysis.rb +78 -0
- data/lib/one_apm/transaction/transaction_apdex.rb +20 -0
- data/lib/one_apm/transaction/transaction_cpu.rb +22 -0
- data/lib/one_apm/transaction/transaction_finish_append.rb +67 -0
- data/lib/one_apm/transaction/transaction_ignore.rb +33 -0
- data/lib/one_apm/transaction/transaction_jruby_functions.rb +40 -0
- data/lib/one_apm/transaction/transaction_metrics.rb +53 -0
- data/lib/one_apm/transaction/transaction_name.rb +90 -0
- data/lib/one_apm/transaction/transaction_namer.rb +49 -0
- data/lib/one_apm/transaction/transaction_sample.rb +204 -0
- data/lib/one_apm/transaction/transaction_sample_builder.rb +168 -0
- data/lib/one_apm/transaction/transaction_state.rb +149 -0
- data/lib/one_apm/transaction/transaction_summary.rb +28 -0
- data/lib/one_apm/transaction/transaction_synthetics.rb +40 -0
- data/lib/one_apm/transaction/transaction_timings.rb +54 -0
- data/lib/one_apm/version.rb +13 -0
- data/lib/oneapm_rpm.rb +16 -0
- data/lib/sequel/extensions/oneapm_instrumentation.rb +84 -0
- data/lib/sequel/plugins/oneapm_instrumentation.rb +66 -0
- data/oneapm.yml +135 -0
- data/oneapm_rpm.gemspec +58 -0
- metadata +474 -0
@@ -0,0 +1,81 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module OneApm
|
4
|
+
module Agent
|
5
|
+
class PipeService
|
6
|
+
attr_reader :channel_id, :buffer, :pipe
|
7
|
+
attr_accessor :request_timeout, :agent_id, :collector
|
8
|
+
|
9
|
+
def initialize(channel_id)
|
10
|
+
@channel_id = channel_id
|
11
|
+
@collector = OneApm::Support::Server.new(:name => 'parent', :port => 0)
|
12
|
+
@pipe = OneApm::Agent::PipeChannelManager.channels[@channel_id]
|
13
|
+
if @pipe && @pipe.parent_pid != $$
|
14
|
+
@pipe.after_fork_in_child
|
15
|
+
else
|
16
|
+
OneApm::Agent.logger.error("No communication channel to parent process, please see https://oneapm.com/docs/ruby/resque-instrumentation for more information.")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def connect(config)
|
21
|
+
nil
|
22
|
+
end
|
23
|
+
|
24
|
+
def get_agent_commands
|
25
|
+
[]
|
26
|
+
end
|
27
|
+
|
28
|
+
def analytic_event_data(events)
|
29
|
+
write_to_pipe(:analytic_event_data, events) if events
|
30
|
+
end
|
31
|
+
|
32
|
+
def custom_event_data(events)
|
33
|
+
write_to_pipe(:custom_event_data, events) if events
|
34
|
+
end
|
35
|
+
|
36
|
+
def metric_data(unsent_timeslice_data)
|
37
|
+
write_to_pipe(:metric_data, unsent_timeslice_data)
|
38
|
+
{}
|
39
|
+
end
|
40
|
+
|
41
|
+
def transaction_sample_data(transactions)
|
42
|
+
write_to_pipe(:transaction_sample_data, transactions) if transactions
|
43
|
+
end
|
44
|
+
|
45
|
+
def error_data(errors)
|
46
|
+
write_to_pipe(:error_data, errors) if errors
|
47
|
+
end
|
48
|
+
|
49
|
+
def sql_trace_data(sql)
|
50
|
+
write_to_pipe(:sql_trace_data, sql) if sql
|
51
|
+
end
|
52
|
+
|
53
|
+
def shutdown(time)
|
54
|
+
@pipe.close if @pipe
|
55
|
+
end
|
56
|
+
|
57
|
+
# Invokes the block it is passed. This is used to implement HTTP
|
58
|
+
# keep-alive in the CollectorService, and is a required interface for any
|
59
|
+
# Service class.
|
60
|
+
def session
|
61
|
+
yield
|
62
|
+
end
|
63
|
+
|
64
|
+
def reset_metric_id_cache
|
65
|
+
# we don't cache metric IDs, so nothing to do
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def marshal_payload(data)
|
71
|
+
OneApm::LanguageSupport.with_cautious_gc do
|
72
|
+
Marshal.dump(data)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def write_to_pipe(endpoint, data)
|
77
|
+
@pipe.write(marshal_payload([endpoint, data])) if @pipe
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module OneApm
|
4
|
+
module Agent
|
5
|
+
class Sampler
|
6
|
+
|
7
|
+
attr_reader :id
|
8
|
+
|
9
|
+
@sampler_classes = []
|
10
|
+
|
11
|
+
class << self
|
12
|
+
|
13
|
+
def named(new_name)
|
14
|
+
@name = new_name
|
15
|
+
end
|
16
|
+
|
17
|
+
def name
|
18
|
+
@name
|
19
|
+
end
|
20
|
+
|
21
|
+
def inherited(subclass)
|
22
|
+
@sampler_classes << subclass
|
23
|
+
end
|
24
|
+
|
25
|
+
def supported_on_this_platform?
|
26
|
+
true
|
27
|
+
end
|
28
|
+
|
29
|
+
def enabled?
|
30
|
+
if @name
|
31
|
+
config_key = "disable_#{@name}_sampler"
|
32
|
+
!(Agent.config[config_key])
|
33
|
+
else
|
34
|
+
true
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def sampler_classes
|
39
|
+
@sampler_classes
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
def initialize(id = nil)
|
45
|
+
@id = id || self.class.name
|
46
|
+
end
|
47
|
+
|
48
|
+
def poll
|
49
|
+
raise "Implement in the subclass"
|
50
|
+
end
|
51
|
+
|
52
|
+
class Unsupported < StandardError; end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module OneApm
|
4
|
+
module Agent
|
5
|
+
class SamplerCollection
|
6
|
+
include Enumerable
|
7
|
+
|
8
|
+
def initialize(event_listener)
|
9
|
+
@samplers = []
|
10
|
+
@event_listener = event_listener
|
11
|
+
@event_listener.subscribe(:before_harvest) { poll_samplers }
|
12
|
+
end
|
13
|
+
|
14
|
+
def each(&blk)
|
15
|
+
@samplers.each(&blk)
|
16
|
+
end
|
17
|
+
|
18
|
+
def clear()
|
19
|
+
@samplers.clear
|
20
|
+
end
|
21
|
+
|
22
|
+
def sampler_class_registered?(sampler_class)
|
23
|
+
self.any? { |s| s.class == sampler_class }
|
24
|
+
end
|
25
|
+
|
26
|
+
# adds samplers to the sampler collection so that they run every
|
27
|
+
# minute. This is dynamically recognized by any class that
|
28
|
+
# subclasses OneApm::Agent::Sampler
|
29
|
+
def load_samplers
|
30
|
+
Sampler.sampler_classes.each do |subclass|
|
31
|
+
add_sampler(subclass)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def poll_samplers
|
36
|
+
@samplers.delete_if do |sampler|
|
37
|
+
begin
|
38
|
+
sampler.poll
|
39
|
+
false
|
40
|
+
rescue => e
|
41
|
+
::OneApm::Agent.logger.warn("Removing #{sampler} from list", e)
|
42
|
+
true # remove the bad sampler
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def add_sampler(sampler_class)
|
48
|
+
supported = sampler_class.supported_on_this_platform?
|
49
|
+
enabled = sampler_class.enabled?
|
50
|
+
if supported && enabled && !sampler_class_registered?(sampler_class)
|
51
|
+
sampler = sampler_class.new
|
52
|
+
sampler.setup_events(@event_listener) if sampler.respond_to?(:setup_events)
|
53
|
+
@samplers << sampler
|
54
|
+
::OneApm::Agent.logger.debug("Registered #{sampler_class.name} for harvest time sampling.")
|
55
|
+
else
|
56
|
+
::OneApm::Agent.logger.debug("#{sampler_class.name} not supported on this platform.")
|
57
|
+
end
|
58
|
+
rescue OneApm::Agent::Sampler::Unsupported => e
|
59
|
+
::OneApm::Agent.logger.info("#{sampler_class.name} not available: #{e}")
|
60
|
+
rescue => e
|
61
|
+
::OneApm::Agent.logger.error("Error registering sampler:", e)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'one_apm/agent/sampler'
|
4
|
+
|
5
|
+
module OneApm
|
6
|
+
module Agent
|
7
|
+
module Samplers
|
8
|
+
class CpuSampler < OneApm::Agent::Sampler
|
9
|
+
attr_reader :last_time
|
10
|
+
|
11
|
+
named :cpu
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@processor_count = OneApm::Agent::SystemInfo.num_logical_processors
|
15
|
+
poll
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.supported_on_this_platform?
|
19
|
+
# Process.times on JRuby < 1.7.0 reports wall clock elapsed time, not actual cpu time used
|
20
|
+
defined?(JRuby) ? (JRUBY_VERSION >= '1.7.0') : true
|
21
|
+
end
|
22
|
+
|
23
|
+
def poll
|
24
|
+
now = Time.now
|
25
|
+
t = Process.times
|
26
|
+
if @last_time
|
27
|
+
elapsed = now - @last_time
|
28
|
+
return if elapsed < 1 # Causing some kind of math underflow
|
29
|
+
|
30
|
+
usertime = t.utime - @last_utime
|
31
|
+
systemtime = t.stime - @last_stime
|
32
|
+
|
33
|
+
if systemtime >= 0
|
34
|
+
OneApm::Agent.record_metric("CPU/System Time", systemtime)
|
35
|
+
OneApm::Agent.record_metric("CPU/System/Utilization", systemtime / (elapsed * @processor_count))
|
36
|
+
end
|
37
|
+
if usertime >= 0
|
38
|
+
OneApm::Agent.record_metric("CPU/User Time", usertime)
|
39
|
+
OneApm::Agent.record_metric("CPU/User/Utilization", usertime / (elapsed * @processor_count))
|
40
|
+
end
|
41
|
+
end
|
42
|
+
@last_utime = t.utime
|
43
|
+
@last_stime = t.stime
|
44
|
+
@last_time = now
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'one_apm/agent/sampler'
|
4
|
+
require 'one_apm/inst/background_job/delayed_job_injection'
|
5
|
+
|
6
|
+
module OneApm
|
7
|
+
module Agent
|
8
|
+
module Samplers
|
9
|
+
# This sampler records the status of your delayed job table once a minute.
|
10
|
+
# It assumes jobs are cleared after being run, and failed jobs are not (otherwise
|
11
|
+
# the failed job metric is useless).
|
12
|
+
#
|
13
|
+
# In earlier versions it will break out the queue length by priority. In later
|
14
|
+
# versions of DJ where distinct queues are supported, it breaks it out by queue name.
|
15
|
+
#
|
16
|
+
class DelayedJobSampler < OneApm::Agent::Sampler
|
17
|
+
named :delayed_job
|
18
|
+
|
19
|
+
# DelayedJob supports multiple backends, only some of which we can
|
20
|
+
# handle. Check whether we think we've got what we need here.
|
21
|
+
def self.supported_backend?
|
22
|
+
::Delayed::Worker.backend.to_s == "Delayed::Backend::ActiveRecord::Job"
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize
|
26
|
+
raise Unsupported, "DJ queue sampler disabled" if Agent.config[:disable_dj]
|
27
|
+
raise Unsupported, "DJ queue sampling unsupported with backend '#{::Delayed::Worker.backend}'" unless self.class.supported_backend?
|
28
|
+
raise Unsupported, "No DJ worker present. Skipping DJ queue sampler" unless OneApm::DelayedJobInjection.worker_name
|
29
|
+
end
|
30
|
+
|
31
|
+
def record_failed_jobs(value)
|
32
|
+
OneApm::Agent.record_metric("Workers/DelayedJob/failed_jobs", value)
|
33
|
+
end
|
34
|
+
|
35
|
+
def record_locked_jobs(value)
|
36
|
+
OneApm::Agent.record_metric("Workers/DelayedJob/locked_jobs", value)
|
37
|
+
end
|
38
|
+
|
39
|
+
FAILED_QUERY = 'failed_at is not NULL'.freeze
|
40
|
+
LOCKED_QUERY = 'locked_by is not NULL'.freeze
|
41
|
+
|
42
|
+
def failed_jobs
|
43
|
+
count(FAILED_QUERY)
|
44
|
+
end
|
45
|
+
|
46
|
+
def locked_jobs
|
47
|
+
count(LOCKED_QUERY)
|
48
|
+
end
|
49
|
+
|
50
|
+
def count(query)
|
51
|
+
if ::ActiveRecord::VERSION::MAJOR.to_i < 4
|
52
|
+
::Delayed::Job.count(query)
|
53
|
+
else
|
54
|
+
::Delayed::Job.where(query).count
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.supported_on_this_platform?
|
59
|
+
defined?(::Delayed::Job)
|
60
|
+
end
|
61
|
+
|
62
|
+
def poll
|
63
|
+
record_failed_jobs(failed_jobs)
|
64
|
+
record_locked_jobs(locked_jobs)
|
65
|
+
record_queue_length_metrics
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def record_queue_length_metrics
|
71
|
+
counts = []
|
72
|
+
counts << record_counts_by("queue", "name") if ::Delayed::Job.instance_methods.include?(:queue)
|
73
|
+
counts << record_counts_by("priority")
|
74
|
+
|
75
|
+
all_metric = "Workers/DelayedJob/queue_length/all"
|
76
|
+
OneApm::Agent.record_metric(all_metric, counts.max)
|
77
|
+
end
|
78
|
+
|
79
|
+
QUEUE_QUERY_CONDITION = 'run_at <= ? and failed_at is NULL'.freeze
|
80
|
+
|
81
|
+
def record_counts_by(column_name, metric_segment = column_name)
|
82
|
+
all_count = 0
|
83
|
+
queue_counts(column_name).each do |column_val, count|
|
84
|
+
all_count += count
|
85
|
+
column_val = "default" if column_val.nil? || column_val == ""
|
86
|
+
metric = "Workers/DelayedJob/queue_length/#{metric_segment}/#{column_val}"
|
87
|
+
OneApm::Agent.record_metric(metric, count)
|
88
|
+
end
|
89
|
+
all_count
|
90
|
+
end
|
91
|
+
|
92
|
+
def queue_counts(column_name)
|
93
|
+
now = ::Delayed::Job.db_time_now
|
94
|
+
# There is not an ActiveRecord syntax for what we're trying to do
|
95
|
+
# here that's valid on 2.x through 4.1, so split it up.
|
96
|
+
result = if ::ActiveRecord::VERSION::MAJOR.to_i < 4
|
97
|
+
::Delayed::Job.count(:group => column_name,
|
98
|
+
:conditions => [QUEUE_QUERY_CONDITION, now])
|
99
|
+
else
|
100
|
+
::Delayed::Job.where(QUEUE_QUERY_CONDITION, now).
|
101
|
+
group(column_name).
|
102
|
+
count
|
103
|
+
end
|
104
|
+
result.to_a
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'one_apm/agent/sampler'
|
4
|
+
|
5
|
+
module OneApm
|
6
|
+
module Agent
|
7
|
+
module Samplers
|
8
|
+
|
9
|
+
class MemorySampler < OneApm::Agent::Sampler
|
10
|
+
named :memory
|
11
|
+
|
12
|
+
attr_accessor :sampler
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
# macos, linux, solaris
|
16
|
+
if defined? JRuby
|
17
|
+
@sampler = JavaHeapSampler.new
|
18
|
+
elsif platform =~ /linux/
|
19
|
+
@sampler = ProcStatus.new
|
20
|
+
if !@sampler.can_run?
|
21
|
+
::OneApm::Agent.logger.debug "Error attempting to use /proc/#{$$}/status file for reading memory. Using ps command instead."
|
22
|
+
@sampler = ShellPS.new("ps -o rsz")
|
23
|
+
else
|
24
|
+
::OneApm::Agent.logger.debug "Using /proc/#{$$}/status for reading process memory."
|
25
|
+
end
|
26
|
+
elsif platform =~ /darwin9/ # 10.5
|
27
|
+
@sampler = ShellPS.new("ps -o rsz")
|
28
|
+
elsif platform =~ /darwin1\d+/ # >= 10.6
|
29
|
+
@sampler = ShellPS.new("ps -o rss")
|
30
|
+
elsif platform =~ /freebsd/
|
31
|
+
@sampler = ShellPS.new("ps -o rss")
|
32
|
+
elsif platform =~ /solaris/
|
33
|
+
@sampler = ShellPS.new("/usr/bin/ps -o rss -p")
|
34
|
+
end
|
35
|
+
|
36
|
+
raise Unsupported, "Unsupported platform for getting memory: #{platform}" if @sampler.nil?
|
37
|
+
raise Unsupported, "Unable to run #{@sampler}" unless @sampler.can_run?
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.supported_on_this_platform?
|
41
|
+
defined?(JRuby) or platform =~ /linux|darwin|freebsd|solaris/
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.platform
|
45
|
+
if RUBY_PLATFORM =~ /java/
|
46
|
+
%x[uname -s].downcase
|
47
|
+
else
|
48
|
+
RUBY_PLATFORM.downcase
|
49
|
+
end
|
50
|
+
end
|
51
|
+
def platform
|
52
|
+
OneApm::Agent::Samplers::MemorySampler.platform
|
53
|
+
end
|
54
|
+
|
55
|
+
def poll
|
56
|
+
sample = @sampler.get_sample
|
57
|
+
if sample
|
58
|
+
OneApm::Agent.record_metric("Memory/Used", sample)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class Base
|
63
|
+
def can_run?
|
64
|
+
return false if @broken
|
65
|
+
m = get_memory rescue nil
|
66
|
+
m && m > 0
|
67
|
+
end
|
68
|
+
|
69
|
+
def get_sample
|
70
|
+
return nil if @broken
|
71
|
+
begin
|
72
|
+
m = get_memory
|
73
|
+
if m.nil?
|
74
|
+
::OneApm::Agent.logger.warn "Unable to get the resident memory for process #{$$}. Disabling memory sampler."
|
75
|
+
@broken = true
|
76
|
+
end
|
77
|
+
return m
|
78
|
+
rescue => e
|
79
|
+
::OneApm::Agent.logger.warn "Unable to get the resident memory for process #{$$}. Disabling memory sampler.", e
|
80
|
+
@broken = true
|
81
|
+
return nil
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
class JavaHeapSampler < Base
|
87
|
+
|
88
|
+
def get_memory
|
89
|
+
raise "Can't sample Java heap unless running in JRuby" unless defined? JRuby
|
90
|
+
java.lang.Runtime.getRuntime.totalMemory / (1024 * 1024).to_f rescue nil
|
91
|
+
end
|
92
|
+
def to_s
|
93
|
+
"JRuby Java heap sampler"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
class ShellPS < Base
|
98
|
+
def initialize(command)
|
99
|
+
super()
|
100
|
+
@command = command
|
101
|
+
end
|
102
|
+
# Returns the amount of resident memory this process is using in MB
|
103
|
+
#
|
104
|
+
def get_memory
|
105
|
+
process = $$
|
106
|
+
memory = `#{@command} #{process}`.split("\n")[1].to_f / 1024.0 rescue nil
|
107
|
+
# if for some reason the ps command doesn't work on the resident os,
|
108
|
+
# then don't execute it any more.
|
109
|
+
raise "Faulty command: `#{@command} #{process}`" if memory.nil? || memory <= 0
|
110
|
+
memory
|
111
|
+
end
|
112
|
+
def to_s
|
113
|
+
"shell command sampler: #{@command}"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# ProcStatus
|
118
|
+
#
|
119
|
+
# A class that samples memory by reading the file /proc/$$/status, which is specific to linux
|
120
|
+
#
|
121
|
+
class ProcStatus < Base
|
122
|
+
|
123
|
+
# Returns the amount of resident memory this process is using in MB
|
124
|
+
#
|
125
|
+
def get_memory
|
126
|
+
proc_status = File.open(proc_status_file, "r") {|f| f.read_nonblock(4096).strip }
|
127
|
+
if proc_status =~ /RSS:\s*(\d+) kB/i
|
128
|
+
return $1.to_f / 1024.0
|
129
|
+
end
|
130
|
+
raise "Unable to find RSS in #{proc_status_file}"
|
131
|
+
end
|
132
|
+
|
133
|
+
def proc_status_file
|
134
|
+
"/proc/#{$$}/status"
|
135
|
+
end
|
136
|
+
|
137
|
+
def to_s
|
138
|
+
"proc status file sampler: #{proc_status_file}"
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|