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,243 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'one_apm/support/language_support'
|
4
|
+
|
5
|
+
module OneApm
|
6
|
+
module Collector
|
7
|
+
class StatsEngine
|
8
|
+
# Handles methods related to actual Metric collection
|
9
|
+
module MetricStats
|
10
|
+
SCOPE_PLACEHOLDER = '__SCOPE__'.freeze
|
11
|
+
|
12
|
+
# Update the unscoped metrics given in metric_names.
|
13
|
+
# metric_names may be either a single name, or an array of names.
|
14
|
+
#
|
15
|
+
# This is an internal method, subject to change at any time. Client apps
|
16
|
+
# and gems should use the public API (OneApm::Agent.record_metric)
|
17
|
+
# instead.
|
18
|
+
#
|
19
|
+
# There are four ways to use this method:
|
20
|
+
#
|
21
|
+
# 1. With a numeric value, it will update the Stats objects associated
|
22
|
+
# with the given metrics by calling record_data_point(value, aux).
|
23
|
+
# aux will be treated in this case as the exclusive time associated
|
24
|
+
# with the call being recorded.
|
25
|
+
#
|
26
|
+
# 2. With a value of :apdex_s, :apdex_t, or :apdex_f, it will treat the
|
27
|
+
# associated stats as an Apdex metric, updating it to reflect the
|
28
|
+
# occurrence of a transaction falling into the given category.
|
29
|
+
# The aux value in this case should be the apdex threshold used in
|
30
|
+
# bucketing the request.
|
31
|
+
#
|
32
|
+
# 3. If a block is given, value and aux will be ignored, and instead the
|
33
|
+
# Stats object associated with each named unscoped metric will be
|
34
|
+
# yielded to the block for customized update logic.
|
35
|
+
#
|
36
|
+
# 4. If value is a Stats instance, it will be merged into the Stats
|
37
|
+
# associated with each named unscoped metric.
|
38
|
+
#
|
39
|
+
# If this method is called during a transaction, the metrics will be
|
40
|
+
# attached to the Transaction, and not merged into the global set until
|
41
|
+
# the end of the transaction.
|
42
|
+
#
|
43
|
+
# Otherwise, the metrics will be recorded directly into the global set
|
44
|
+
# of metrics, under a lock.
|
45
|
+
#
|
46
|
+
# @api private
|
47
|
+
#
|
48
|
+
def tl_record_unscoped_metrics(metric_names, value=nil, aux=nil, &blk)
|
49
|
+
state = OneApm::TransactionState.tl_get
|
50
|
+
record_unscoped_metrics(state, metric_names, value, aux, &blk)
|
51
|
+
end
|
52
|
+
|
53
|
+
def record_unscoped_metrics(state, metric_names, value=nil, aux=nil, &blk)
|
54
|
+
txn = state.current_transaction
|
55
|
+
if txn
|
56
|
+
txn.metrics.record_unscoped(metric_names, value, aux, &blk)
|
57
|
+
else
|
58
|
+
specs = coerce_to_metric_spec_array(metric_names, nil)
|
59
|
+
with_stats_lock do
|
60
|
+
@stats_hash.record(specs, value, aux, &blk)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Like tl_record_unscoped_metrics, but records a scoped metric as well.
|
66
|
+
#
|
67
|
+
# This is an internal method, subject to change at any time. Client apps
|
68
|
+
# and gems should use the public API (OneApm::Agent.record_metric)
|
69
|
+
# instead.
|
70
|
+
#
|
71
|
+
# The given scoped_metric will be recoded as both a scoped *and* an
|
72
|
+
# unscoped metric. The summary_metrics will be recorded as unscoped
|
73
|
+
# metrics only.
|
74
|
+
#
|
75
|
+
# If called during a transaction, all metrics will be attached to the
|
76
|
+
# Transaction, and not merged into the global set of metrics until the
|
77
|
+
# end of the transaction.
|
78
|
+
#
|
79
|
+
# If called outside of a transaction, only the *unscoped* metrics will
|
80
|
+
# be recorded, directly into the global set of metrics (under a lock).
|
81
|
+
#
|
82
|
+
# @api private
|
83
|
+
#
|
84
|
+
def tl_record_scoped_and_unscoped_metrics(scoped_metric, summary_metrics=nil, value=nil, aux=nil, &blk)
|
85
|
+
state = OneApm::TransactionState.tl_get
|
86
|
+
record_scoped_and_unscoped_metrics(state, scoped_metric, summary_metrics, value, aux, &blk)
|
87
|
+
end
|
88
|
+
|
89
|
+
def record_scoped_and_unscoped_metrics(state, scoped_metric, summary_metrics=nil, value=nil, aux=nil, &blk)
|
90
|
+
txn = state.current_transaction
|
91
|
+
if txn
|
92
|
+
txn.metrics.record_scoped(scoped_metric, value, aux, &blk)
|
93
|
+
txn.metrics.record_unscoped(scoped_metric, value, aux, &blk)
|
94
|
+
if summary_metrics
|
95
|
+
txn.metrics.record_unscoped(summary_metrics, value, aux, &blk)
|
96
|
+
end
|
97
|
+
else
|
98
|
+
specs = coerce_to_metric_spec_array(scoped_metric, nil)
|
99
|
+
if summary_metrics
|
100
|
+
specs.concat(coerce_to_metric_spec_array(summary_metrics, nil))
|
101
|
+
end
|
102
|
+
with_stats_lock do
|
103
|
+
@stats_hash.record(specs, value, aux, &blk)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# This method is deprecated and not thread safe, and should not be used
|
109
|
+
# by any new client code. Use OneApm::Agent.record_metric instead.
|
110
|
+
#
|
111
|
+
# Lookup the Stats object for a given unscoped metric, returning a new
|
112
|
+
# Stats object if one did not exist previously.
|
113
|
+
#
|
114
|
+
# @api public
|
115
|
+
# @deprecated
|
116
|
+
#
|
117
|
+
def get_stats_no_scope(metric_name)
|
118
|
+
get_stats(metric_name, false)
|
119
|
+
end
|
120
|
+
|
121
|
+
# This method is deprecated and not thread safe, and should not be used
|
122
|
+
# by any new client code. Use OneApm::Agent.record_metric instead.
|
123
|
+
#
|
124
|
+
# If scoped_metric_only is true, only a scoped metric is created (used
|
125
|
+
# by rendering metrics which by definition are per controller only)
|
126
|
+
# Leaving second, unused parameter for compatibility
|
127
|
+
#
|
128
|
+
# @api public
|
129
|
+
# @deprecated
|
130
|
+
#
|
131
|
+
def get_stats(metric_name, _ = true, scoped_metric_only = false, scope = nil)
|
132
|
+
stats = nil
|
133
|
+
with_stats_lock do
|
134
|
+
if scoped_metric_only
|
135
|
+
stats = @stats_hash[OneApm::MetricSpec.new(metric_name, scope)]
|
136
|
+
else
|
137
|
+
unscoped_spec = OneApm::MetricSpec.new(metric_name)
|
138
|
+
unscoped_stats = @stats_hash[unscoped_spec]
|
139
|
+
if scope && scope != metric_name
|
140
|
+
scoped_spec = OneApm::MetricSpec.new(metric_name, scope)
|
141
|
+
scoped_stats = @stats_hash[scoped_spec]
|
142
|
+
stats = OneApm::Metrics::ChainedStats.new(scoped_stats, unscoped_stats)
|
143
|
+
else
|
144
|
+
stats = unscoped_stats
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
stats
|
149
|
+
end
|
150
|
+
|
151
|
+
# Returns a stat if one exists, otherwise returns nil.
|
152
|
+
def lookup_stats(metric_name, scope_name = '')
|
153
|
+
spec = OneApm::MetricSpec.new(metric_name, scope_name)
|
154
|
+
with_stats_lock do
|
155
|
+
@stats_hash.has_key?(spec) ? @stats_hash[spec] : nil
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
# Helper for recording a straight value into the count
|
160
|
+
def tl_record_supportability_metric_count(metric, value)
|
161
|
+
real_name = "Supportability/#{metric}"
|
162
|
+
tl_record_unscoped_metrics(real_name) do |stat|
|
163
|
+
stat.call_count = value
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def reset!
|
168
|
+
with_stats_lock do
|
169
|
+
old = @stats_hash
|
170
|
+
@stats_hash = StatsHash.new
|
171
|
+
old
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
# merge data from previous harvests into this stats engine
|
176
|
+
def merge!(other_stats_hash)
|
177
|
+
with_stats_lock do
|
178
|
+
@stats_hash.merge!(other_stats_hash)
|
179
|
+
@stats_hash
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def merge_transaction_metrics!(txn_metrics, scope)
|
184
|
+
with_stats_lock do
|
185
|
+
@stats_hash.merge_transaction_metrics!(txn_metrics, scope)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
def harvest!
|
190
|
+
now = Time.now
|
191
|
+
snapshot = reset!
|
192
|
+
snapshot = apply_rules_to_metric_data(@metric_rules, snapshot)
|
193
|
+
snapshot.harvested_at = now
|
194
|
+
snapshot
|
195
|
+
end
|
196
|
+
|
197
|
+
def apply_rules_to_metric_data(rules_engine, stats_hash)
|
198
|
+
renamed_stats = OneApm::Collector::StatsHash.new(stats_hash.started_at)
|
199
|
+
stats_hash.each do |spec, stats|
|
200
|
+
new_name = rules_engine.rename(spec.name)
|
201
|
+
unless new_name.nil?
|
202
|
+
new_spec = OneApm::MetricSpec.new(new_name, spec.scope)
|
203
|
+
renamed_stats[new_spec].merge!(stats)
|
204
|
+
end
|
205
|
+
end
|
206
|
+
renamed_stats
|
207
|
+
end
|
208
|
+
|
209
|
+
def coerce_to_metric_spec_array(metric_names_or_specs, scope)
|
210
|
+
specs = []
|
211
|
+
Array(metric_names_or_specs).map do |name_or_spec|
|
212
|
+
case name_or_spec
|
213
|
+
when String
|
214
|
+
specs << OneApm::MetricSpec.new(name_or_spec)
|
215
|
+
specs << OneApm::MetricSpec.new(name_or_spec, scope) if scope
|
216
|
+
when OneApm::MetricSpec
|
217
|
+
specs << name_or_spec
|
218
|
+
end
|
219
|
+
end
|
220
|
+
specs
|
221
|
+
end
|
222
|
+
|
223
|
+
# For use by test code only.
|
224
|
+
def clear_stats
|
225
|
+
reset!
|
226
|
+
OneApm::Agent::BusyCalculator.reset
|
227
|
+
end
|
228
|
+
|
229
|
+
# Returns all of the metric names of all the stats in the engine.
|
230
|
+
# For use by test code only.
|
231
|
+
def metrics
|
232
|
+
with_stats_lock do
|
233
|
+
@stats_hash.keys.map { |spec| spec.to_s }
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
def metric_specs
|
238
|
+
with_stats_lock { @stats_hash.keys }
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# A Hash-descended class for storing metric data in the OneApm Agent.
|
4
|
+
#
|
5
|
+
# Keys are OneApm::MetricSpec objects.
|
6
|
+
# Values are OneApm::Metrics::Stats objects.
|
7
|
+
#
|
8
|
+
# Missing keys will be automatically created as empty OneApm::Metrics::Stats
|
9
|
+
# instances, so use has_key? explicitly to check for key existence.
|
10
|
+
#
|
11
|
+
# Note that instances of this class are intended to be append-only with respect
|
12
|
+
# to new metrics. That is, you should not attempt to *remove* an entry after it
|
13
|
+
# has been added, only update it (create a new instance if you need to start
|
14
|
+
# over with a blank slate).
|
15
|
+
#
|
16
|
+
# This class makes no provisions for safe usage from multiple threads, such
|
17
|
+
# measures should be externally provided.
|
18
|
+
|
19
|
+
require 'one_apm/errors/internal_agent_error'
|
20
|
+
|
21
|
+
module OneApm
|
22
|
+
module Collector
|
23
|
+
class StatsHash < ::Hash
|
24
|
+
|
25
|
+
attr_accessor :started_at, :harvested_at
|
26
|
+
|
27
|
+
def initialize(started_at=Time.now)
|
28
|
+
@started_at = started_at.to_f
|
29
|
+
super() { |hash, key| hash[key] = OneApm::Metrics::Stats.new }
|
30
|
+
end
|
31
|
+
|
32
|
+
def marshal_dump
|
33
|
+
[@started_at, Hash[self]]
|
34
|
+
end
|
35
|
+
|
36
|
+
def marshal_load(data)
|
37
|
+
@started_at = data.shift
|
38
|
+
self.merge!(data.shift)
|
39
|
+
end
|
40
|
+
|
41
|
+
def ==(other)
|
42
|
+
Hash[self] == Hash[other]
|
43
|
+
end
|
44
|
+
|
45
|
+
class StatsHashLookupError < OneApm::Agent::InternalAgentError
|
46
|
+
def initialize(original_error, hash, metric_spec)
|
47
|
+
super("Lookup error in StatsHash: #{original_error.class}: #{original_error.message}. Falling back adding #{metric_spec.inspect}")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def record(metric_specs, value=nil, aux=nil, &blk)
|
52
|
+
Array(metric_specs).each do |metric_spec|
|
53
|
+
stats = nil
|
54
|
+
begin
|
55
|
+
stats = self[metric_spec]
|
56
|
+
rescue NoMethodError => e
|
57
|
+
# This only happen in the case of a corrupted default_proc
|
58
|
+
# Side-step it manually, notice the issue, and carry on....
|
59
|
+
OneApm::Agent.instance.error_collector. \
|
60
|
+
notice_agent_error(StatsHashLookupError.new(e, self, metric_spec))
|
61
|
+
|
62
|
+
stats = OneApm::Metrics::Stats.new
|
63
|
+
self[metric_spec] = stats
|
64
|
+
|
65
|
+
# Try to restore the default_proc so we won't continually trip the error
|
66
|
+
if respond_to?(:default_proc=)
|
67
|
+
self.default_proc = Proc.new { |hash, key| hash[key] = OneApm::Metrics::Stats.new }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
stats.record(value, aux, &blk)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def merge!(other)
|
76
|
+
if other.is_a?(StatsHash) && other.started_at < @started_at
|
77
|
+
@started_at = other.started_at
|
78
|
+
end
|
79
|
+
other.each do |key, val|
|
80
|
+
merge_or_insert(key, val)
|
81
|
+
end
|
82
|
+
self
|
83
|
+
end
|
84
|
+
|
85
|
+
def merge_transaction_metrics!(txn_metrics, scope)
|
86
|
+
txn_metrics.each_unscoped do |name, stats|
|
87
|
+
spec = OneApm::MetricSpec.new(name)
|
88
|
+
merge_or_insert(spec, stats)
|
89
|
+
end
|
90
|
+
txn_metrics.each_scoped do |name, stats|
|
91
|
+
spec = OneApm::MetricSpec.new(name, scope)
|
92
|
+
merge_or_insert(spec, stats)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def merge_or_insert(metric_spec, stats)
|
97
|
+
if self.has_key?(metric_spec)
|
98
|
+
self[metric_spec].merge!(stats)
|
99
|
+
else
|
100
|
+
self[metric_spec] = stats
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,429 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'forwardable'
|
4
|
+
require 'one_apm/support/dotted_hash'
|
5
|
+
require 'one_apm/configuration/yaml_source'
|
6
|
+
require 'one_apm/configuration/server_source'
|
7
|
+
require 'one_apm/configuration/manual_source'
|
8
|
+
require 'one_apm/configuration/default_source'
|
9
|
+
require 'one_apm/configuration/environment_source'
|
10
|
+
require 'one_apm/configuration/high_security_source'
|
11
|
+
|
12
|
+
module OneApm
|
13
|
+
module Configuration
|
14
|
+
|
15
|
+
MASK_DEFAULTS = {
|
16
|
+
:'thread_profiler' => Proc.new { !OneApm::Agent::Threading::BacktraceService.is_supported? },
|
17
|
+
:'thread_profiler.enabled' => Proc.new { !OneApm::Agent::Threading::BacktraceService.is_supported? }
|
18
|
+
}
|
19
|
+
|
20
|
+
class Manager
|
21
|
+
|
22
|
+
attr_reader :stripped_exceptions_whitelist
|
23
|
+
|
24
|
+
def initialize
|
25
|
+
reset_to_defaults
|
26
|
+
@callbacks = Hash.new {|hash,key| hash[key] = [] }
|
27
|
+
|
28
|
+
register_callback(:'strip_exception_messages.whitelist') do |whitelist|
|
29
|
+
if whitelist
|
30
|
+
@stripped_exceptions_whitelist = parse_constant_list(whitelist).compact
|
31
|
+
else
|
32
|
+
@stripped_exceptions_whitelist = []
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Defining these explicitly saves object allocations that we incur
|
38
|
+
# if we use Forwardable and def_delegators.
|
39
|
+
def [](key)
|
40
|
+
@cache[key]
|
41
|
+
end
|
42
|
+
|
43
|
+
def has_key?(key)
|
44
|
+
@cache.has_key?[key]
|
45
|
+
end
|
46
|
+
|
47
|
+
def keys
|
48
|
+
@cache.keys
|
49
|
+
end
|
50
|
+
|
51
|
+
def add_config_for_testing(source, level=0)
|
52
|
+
raise 'Invalid config type for testing' unless [Hash, OneApm::Support::DottedHash].include?(source.class)
|
53
|
+
invoke_callbacks(:add, source)
|
54
|
+
@configs_for_testing << [source.freeze, level]
|
55
|
+
reset_cache
|
56
|
+
log_config(:add, source)
|
57
|
+
end
|
58
|
+
|
59
|
+
def remove_config_type(sym)
|
60
|
+
source = case sym
|
61
|
+
when :high_security then @high_security_source
|
62
|
+
when :environment then @environment_source
|
63
|
+
when :server then @server_source
|
64
|
+
when :manual then @manual_source
|
65
|
+
when :yaml then @yaml_source
|
66
|
+
when :default then @default_source
|
67
|
+
end
|
68
|
+
|
69
|
+
remove_config(source)
|
70
|
+
end
|
71
|
+
|
72
|
+
def remove_config(source)
|
73
|
+
case source
|
74
|
+
when HighSecuritySource then @high_security_source = nil
|
75
|
+
when EnvironmentSource then @environment_source = nil
|
76
|
+
when ServerSource then @server_source = nil
|
77
|
+
when ManualSource then @manual_source = nil
|
78
|
+
when YamlSource then @yaml_source = nil
|
79
|
+
when DefaultSource then @default_source = nil
|
80
|
+
else
|
81
|
+
@configs_for_testing.delete_if {|src,lvl| src == source}
|
82
|
+
end
|
83
|
+
|
84
|
+
reset_cache
|
85
|
+
invoke_callbacks(:remove, source)
|
86
|
+
log_config(:remove, source)
|
87
|
+
end
|
88
|
+
|
89
|
+
def replace_or_add_config(source)
|
90
|
+
source.freeze
|
91
|
+
was_finished = finished_configuring?
|
92
|
+
|
93
|
+
invoke_callbacks(:add, source)
|
94
|
+
case source
|
95
|
+
when HighSecuritySource then @high_security_source = source
|
96
|
+
when EnvironmentSource then @environment_source = source
|
97
|
+
when ServerSource then @server_source = source
|
98
|
+
when ManualSource then @manual_source = source
|
99
|
+
when YamlSource then @yaml_source = source
|
100
|
+
when DefaultSource then @default_source = source
|
101
|
+
else
|
102
|
+
OneApm::Agent.logger.warn("Invalid config format; config will be ignored: #{source}")
|
103
|
+
end
|
104
|
+
|
105
|
+
reset_cache
|
106
|
+
log_config(:add, source)
|
107
|
+
|
108
|
+
notify_finished_configuring if !was_finished && finished_configuring?
|
109
|
+
end
|
110
|
+
|
111
|
+
def source(key)
|
112
|
+
config_stack.each do |config|
|
113
|
+
if config.respond_to?(key.to_sym) || config.has_key?(key.to_sym)
|
114
|
+
return config
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def fetch(key)
|
120
|
+
config_stack.each do |config|
|
121
|
+
next unless config
|
122
|
+
accessor = key.to_sym
|
123
|
+
|
124
|
+
if config.has_key?(accessor)
|
125
|
+
evaluated = evaluate_procs(config[accessor])
|
126
|
+
|
127
|
+
begin
|
128
|
+
return apply_transformations(accessor, evaluated)
|
129
|
+
rescue
|
130
|
+
next
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
nil
|
136
|
+
end
|
137
|
+
|
138
|
+
def evaluate_procs(value)
|
139
|
+
if value.respond_to?(:call)
|
140
|
+
instance_eval(&value)
|
141
|
+
else
|
142
|
+
value
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def apply_transformations(key, value)
|
147
|
+
if transform = transform_from_default(key)
|
148
|
+
begin
|
149
|
+
transform.call(value)
|
150
|
+
rescue => e
|
151
|
+
::OneApm::Agent.logger.error("Error applying transformation for #{key}, falling back to #{value}.", e)
|
152
|
+
raise e
|
153
|
+
end
|
154
|
+
else
|
155
|
+
value
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def transform_from_default(key)
|
160
|
+
::OneApm::Configuration::DefaultSource.transform_for(key)
|
161
|
+
end
|
162
|
+
|
163
|
+
def register_callback(key, &proc)
|
164
|
+
@callbacks[key] << proc
|
165
|
+
proc.call(@cache[key])
|
166
|
+
end
|
167
|
+
|
168
|
+
def invoke_callbacks(direction, source)
|
169
|
+
return unless source
|
170
|
+
source.keys.each do |key|
|
171
|
+
|
172
|
+
if @cache[key] != source[key]
|
173
|
+
@callbacks[key].each do |proc|
|
174
|
+
if direction == :add
|
175
|
+
proc.call(source[key])
|
176
|
+
else
|
177
|
+
proc.call(@cache[key])
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def notify_finished_configuring
|
185
|
+
OneApm::Agent.instance.events.notify(:finished_configuring)
|
186
|
+
end
|
187
|
+
|
188
|
+
def finished_configuring?
|
189
|
+
!@server_source.nil?
|
190
|
+
end
|
191
|
+
|
192
|
+
def flattened
|
193
|
+
config_stack.reverse.inject({}) do |flat,layer|
|
194
|
+
thawed_layer = layer.to_hash.dup
|
195
|
+
thawed_layer.each do |k,v|
|
196
|
+
begin
|
197
|
+
thawed_layer[k] = instance_eval(&v) if v.respond_to?(:call)
|
198
|
+
rescue => e
|
199
|
+
::OneApm::Agent.logger.debug("#{e.class.name} : #{e.message} - when accessing config key #{k}")
|
200
|
+
thawed_layer[k] = nil
|
201
|
+
end
|
202
|
+
thawed_layer.delete(:config)
|
203
|
+
end
|
204
|
+
flat.merge(thawed_layer.to_hash)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
def apply_mask(hash)
|
209
|
+
MASK_DEFAULTS. \
|
210
|
+
select {|_, proc| proc.call}. \
|
211
|
+
each {|key, _| hash.delete(key) }
|
212
|
+
hash
|
213
|
+
end
|
214
|
+
|
215
|
+
def to_collector_hash
|
216
|
+
OneApm::Support::DottedHash.new(apply_mask(flattened)).to_hash.delete_if do |k, v|
|
217
|
+
default = DEFAULTS[k]
|
218
|
+
if default
|
219
|
+
default[:local_only]
|
220
|
+
else
|
221
|
+
# In our tests, we add totally bogus configs, because testing.
|
222
|
+
# In those cases, there will be no default. So we'll just let
|
223
|
+
# them through.
|
224
|
+
false
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
def app_names
|
230
|
+
case OneApm::Agent.config[:app_name]
|
231
|
+
when Array then OneApm::Agent.config[:app_name]
|
232
|
+
when String then OneApm::Agent.config[:app_name].split(';')
|
233
|
+
else []
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
MALFORMED_LABELS_WARNING = "Skipping malformed labels configuration"
|
238
|
+
PARSING_LABELS_FAILURE = "Failure during parsing labels. Ignoring and carrying on with connect."
|
239
|
+
|
240
|
+
MAX_LABEL_COUNT = 64
|
241
|
+
MAX_LABEL_LENGTH = 255
|
242
|
+
|
243
|
+
def parsed_labels
|
244
|
+
case OneApm::Agent.config[:labels]
|
245
|
+
when String
|
246
|
+
parse_labels_from_string
|
247
|
+
else
|
248
|
+
parse_labels_from_dictionary
|
249
|
+
end
|
250
|
+
rescue => e
|
251
|
+
OneApm::Agent.logger.error(PARSING_LABELS_FAILURE, e)
|
252
|
+
[]
|
253
|
+
end
|
254
|
+
|
255
|
+
def parse_labels_from_string
|
256
|
+
labels = OneApm::Agent.config[:labels]
|
257
|
+
label_pairs = break_label_string_into_pairs(labels)
|
258
|
+
make_label_hash(label_pairs, labels)
|
259
|
+
end
|
260
|
+
|
261
|
+
def break_label_string_into_pairs(labels)
|
262
|
+
stripped_labels = labels.strip
|
263
|
+
stripped_labels.split(';').map do |pair|
|
264
|
+
pair.split(':').map(&:strip)
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
def valid_label_pairs?(label_pairs)
|
269
|
+
label_pairs.all? do |pair|
|
270
|
+
pair.length == 2 && valid_label_item?(pair.first) && valid_label_item?(pair.last)
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
def valid_label_item?(item)
|
275
|
+
case item
|
276
|
+
when String then !item.empty?
|
277
|
+
when Numeric then true
|
278
|
+
when true then true
|
279
|
+
when false then true
|
280
|
+
else false
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
def make_label_hash(pairs, labels = nil)
|
285
|
+
# This can accept a hash, so force it down to an array of pairs first
|
286
|
+
pairs = Array(pairs)
|
287
|
+
|
288
|
+
unless valid_label_pairs?(pairs)
|
289
|
+
OneApm::Agent.logger.warn("#{MALFORMED_LABELS_WARNING}: #{labels||pairs}")
|
290
|
+
return []
|
291
|
+
end
|
292
|
+
|
293
|
+
pairs = limit_number_of_labels(pairs)
|
294
|
+
pairs = remove_duplicates(pairs)
|
295
|
+
pairs.map do |key, value|
|
296
|
+
{
|
297
|
+
'label_type' => truncate(key),
|
298
|
+
'label_value' => truncate(value.to_s, key)
|
299
|
+
}
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
def truncate(text, key=nil)
|
304
|
+
if text.length > MAX_LABEL_LENGTH
|
305
|
+
if key
|
306
|
+
msg = "The value for the label '#{key}' is longer than the allowed #{MAX_LABEL_LENGTH} and will be truncated. Value = '#{text}'"
|
307
|
+
else
|
308
|
+
msg = "Label name longer than the allowed #{MAX_LABEL_LENGTH} will be truncated. Name = '#{text}'"
|
309
|
+
end
|
310
|
+
OneApm::Agent.logger.warn(msg)
|
311
|
+
text[0..MAX_LABEL_LENGTH-1]
|
312
|
+
else
|
313
|
+
text
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
def limit_number_of_labels(pairs)
|
318
|
+
if pairs.length > MAX_LABEL_COUNT
|
319
|
+
OneApm::Agent.logger.warn("Too many labels defined. Only taking first #{MAX_LABEL_COUNT}")
|
320
|
+
pairs[0...64]
|
321
|
+
else
|
322
|
+
pairs
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
# We only take the last value provided for a given label type key
|
327
|
+
def remove_duplicates(pairs)
|
328
|
+
grouped_by_type = pairs.group_by(&:first)
|
329
|
+
grouped_by_type.values.map(&:last)
|
330
|
+
end
|
331
|
+
|
332
|
+
def parse_labels_from_dictionary
|
333
|
+
make_label_hash(OneApm::Agent.config[:labels])
|
334
|
+
end
|
335
|
+
|
336
|
+
# Generally only useful during initial construction and tests
|
337
|
+
def reset_to_defaults
|
338
|
+
@high_security_source = nil
|
339
|
+
@environment_source = EnvironmentSource.new
|
340
|
+
@server_source = nil
|
341
|
+
@manual_source = nil
|
342
|
+
@yaml_source = nil
|
343
|
+
@default_source = DefaultSource.new
|
344
|
+
|
345
|
+
@configs_for_testing = []
|
346
|
+
|
347
|
+
reset_cache
|
348
|
+
end
|
349
|
+
|
350
|
+
def reset_cache
|
351
|
+
@cache = Hash.new {|hash,key| hash[key] = self.fetch(key) }
|
352
|
+
end
|
353
|
+
|
354
|
+
def log_config(direction, source)
|
355
|
+
# Just generating this log message (specifically calling
|
356
|
+
# flattened.inspect) is expensive enough that we don't want to do it
|
357
|
+
# unless we're actually going to be logging the message based on our
|
358
|
+
# current log level.
|
359
|
+
::OneApm::Agent.logger.debug do
|
360
|
+
"Updating config (#{direction}) from #{source.class}. Results: #{flattened.inspect}"
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
def delete_all_configs_for_testing
|
365
|
+
@high_security_source = nil
|
366
|
+
@environment_source = nil
|
367
|
+
@server_source = nil
|
368
|
+
@manual_source = nil
|
369
|
+
@yaml_source = nil
|
370
|
+
@default_source = nil
|
371
|
+
@configs_for_testing = []
|
372
|
+
end
|
373
|
+
|
374
|
+
def num_configs_for_testing
|
375
|
+
config_stack.size
|
376
|
+
end
|
377
|
+
|
378
|
+
def config_classes_for_testing
|
379
|
+
config_stack.map(&:class)
|
380
|
+
end
|
381
|
+
|
382
|
+
private
|
383
|
+
|
384
|
+
def config_stack
|
385
|
+
stack = [
|
386
|
+
@high_security_source,
|
387
|
+
@environment_source,
|
388
|
+
@server_source,
|
389
|
+
@manual_source,
|
390
|
+
@yaml_source,
|
391
|
+
@default_source
|
392
|
+
]
|
393
|
+
|
394
|
+
stack.compact!
|
395
|
+
|
396
|
+
@configs_for_testing.each do |config, at_start|
|
397
|
+
if at_start
|
398
|
+
stack.insert(0, config)
|
399
|
+
else
|
400
|
+
stack.push(config)
|
401
|
+
end
|
402
|
+
end
|
403
|
+
|
404
|
+
stack
|
405
|
+
end
|
406
|
+
|
407
|
+
def parse_constant_list(list)
|
408
|
+
list.split(/\s*,\s*/).map do |class_name|
|
409
|
+
const = constantize(class_name)
|
410
|
+
|
411
|
+
unless const
|
412
|
+
OneApm::Agent.logger.warn "Configuration referenced undefined constant: #{class_name}"
|
413
|
+
end
|
414
|
+
|
415
|
+
const
|
416
|
+
end
|
417
|
+
end
|
418
|
+
|
419
|
+
def constantize(class_name)
|
420
|
+
namespaces = class_name.split('::')
|
421
|
+
|
422
|
+
namespaces.inject(Object) do |namespace, name|
|
423
|
+
return unless namespace
|
424
|
+
namespace.const_get(name) if namespace.const_defined?(name)
|
425
|
+
end
|
426
|
+
end
|
427
|
+
end
|
428
|
+
end
|
429
|
+
end
|