Class: DependencyDetection::Dependent
- Inherits:
-
Object
- Object
- DependencyDetection::Dependent
- Defined in:
- lib/new_relic/dependency_detection.rb
Constant Summary collapse
- VALID_CONFIG_VALUES =
[:auto, :disabled, :prepend, :chain]
- AUTO_CONFIG_VALUE =
Instance Attribute Summary collapse
- #config_name ⇒ Object
-
#dependencies ⇒ Object
readonly
Returns the value of attribute dependencies.
-
#executed ⇒ Object
readonly
Returns the value of attribute executed.
-
#name ⇒ Object
Returns the value of attribute name.
-
#prepend_conflicts ⇒ Object
readonly
Returns the value of attribute prepend_conflicts.
Instance Method Summary collapse
- #allowed_by_config? ⇒ Boolean
- #chain_instrument(instrumenting_module, supportability_name = nil) ⇒ Object
- #chain_instrument_target(target, instrumenting_module, supportability_name = nil) ⇒ Object
- #check_dependencies ⇒ Object
- #config_key ⇒ Object
- #config_value ⇒ Object
- #configure_as_unsatisfied ⇒ Object
- #configure_with(new_config_name) ⇒ Object
- #conflicts_with_prepend(&block) ⇒ Object
- #dependencies_satisfied? ⇒ Boolean
- #depends_on(&block) ⇒ Object
-
#deprecated_disabled_configured? ⇒ Boolean
TODO: MAJOR VERSION will only return true if a disabled key is found and is truthy.
- #execute ⇒ Object
- #executed! ⇒ Object
- #executes(&block) ⇒ Object
-
#extract_supportability_name(instrumenting_module) ⇒ Object
Extracts the instrumented library name from the instrumenting module’s name Given “NewRelic::Agent::Instrumentation::NetHTTP::Prepend” Will extract “NetHTTP” which is in the 2nd to last spot.
-
#fetch_config_value(key) ⇒ Object
fetches and transform potentially invalid value given to one of the valid config values logs the resolved value during debug mode.
-
#initialize ⇒ Dependent
constructor
A new instance of Dependent.
- #log_and_instrument(method, instrumenting_module, supportability_name) ⇒ Object
- #named(new_name) ⇒ Object
- #prepend_conflicts? ⇒ Boolean
- #prepend_instrument(target_class, instrumenting_module, supportability_name = nil) ⇒ Object
- #source_location_for(klass, method_name) ⇒ Object
-
#update_config_value(use_prepend) ⇒ Object
update any :auto config value to be either :prepend or :chain after auto determination has selected one of those to use.
- #use_prepend? ⇒ Boolean
-
#valid_config_value(retrieved_value) ⇒ Object
returns only a valid value for instrumentation configuration If user uses “enabled” it’s converted to “auto”.
Constructor Details
#initialize ⇒ Dependent
Returns a new instance of Dependent.
53 54 55 56 57 58 59 |
# File 'lib/new_relic/dependency_detection.rb', line 53 def initialize @dependencies = [] @executes = [] @prepend_conflicts = [] @name = nil @config_name = nil end |
Instance Attribute Details
#config_name ⇒ Object
49 50 51 |
# File 'lib/new_relic/dependency_detection.rb', line 49 def config_name @config_name || @name end |
#dependencies ⇒ Object (readonly)
Returns the value of attribute dependencies.
42 43 44 |
# File 'lib/new_relic/dependency_detection.rb', line 42 def dependencies @dependencies end |
#executed ⇒ Object (readonly)
Returns the value of attribute executed.
39 40 41 |
# File 'lib/new_relic/dependency_detection.rb', line 39 def executed @executed end |
#name ⇒ Object
Returns the value of attribute name.
40 41 42 |
# File 'lib/new_relic/dependency_detection.rb', line 40 def name @name end |
#prepend_conflicts ⇒ Object (readonly)
Returns the value of attribute prepend_conflicts.
43 44 45 |
# File 'lib/new_relic/dependency_detection.rb', line 43 def prepend_conflicts @prepend_conflicts end |
Instance Method Details
#allowed_by_config? ⇒ Boolean
143 144 145 |
# File 'lib/new_relic/dependency_detection.rb', line 143 def allowed_by_config? !(disabled_configured? || deprecated_disabled_configured?) end |
#chain_instrument(instrumenting_module, supportability_name = nil) ⇒ Object
100 101 102 103 104 |
# File 'lib/new_relic/dependency_detection.rb', line 100 def chain_instrument(instrumenting_module, supportability_name = nil) log_and_instrument('MethodChaining', instrumenting_module, supportability_name) do instrumenting_module.instrument! end end |
#chain_instrument_target(target, instrumenting_module, supportability_name = nil) ⇒ Object
106 107 108 109 110 111 |
# File 'lib/new_relic/dependency_detection.rb', line 106 def chain_instrument_target(target, instrumenting_module, supportability_name = nil) NewRelic::Agent.logger.info("Installing deferred #{target} instrumentation") log_and_instrument('MethodChaining', instrumenting_module, supportability_name) do instrumenting_module.instrument!(target) end end |
#check_dependencies ⇒ Object
126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/new_relic/dependency_detection.rb', line 126 def check_dependencies return false unless allowed_by_config? && dependencies dependencies.all? do |dep| begin dep.call rescue => err NewRelic::Agent.logger.error("Error while detecting #{self.name}:", err) false end end end |
#config_key ⇒ Object
164 165 166 167 168 |
# File 'lib/new_relic/dependency_detection.rb', line 164 def config_key return nil if self.config_name.nil? @config_key ||= "instrumentation.#{self.config_name}".to_sym end |
#config_value ⇒ Object
202 203 204 205 206 |
# File 'lib/new_relic/dependency_detection.rb', line 202 def config_value return AUTO_CONFIG_VALUE unless config_key fetch_config_value(config_key) end |
#configure_as_unsatisfied ⇒ Object
65 66 67 68 69 70 71 72 73 74 |
# File 'lib/new_relic/dependency_detection.rb', line 65 def configure_as_unsatisfied # TODO: currently using :unsatisfied for Padrino will clobber the value # already set for Sinatra, so skip Padrino and circle back with a # new Padrino specific solution in the future. # # https://github.com/newrelic/newrelic-ruby-agent/issues/2912 return if name == :padrino NewRelic::Agent.config.instance_variable_get(:@cache)[config_key] = :unsatisfied end |
#configure_with(new_config_name) ⇒ Object
212 213 214 |
# File 'lib/new_relic/dependency_detection.rb', line 212 def configure_with(new_config_name) self.config_name = new_config_name end |
#conflicts_with_prepend(&block) ⇒ Object
220 221 222 |
# File 'lib/new_relic/dependency_detection.rb', line 220 def conflicts_with_prepend(&block) @prepend_conflicts << block if block end |
#dependencies_satisfied? ⇒ Boolean
61 62 63 |
# File 'lib/new_relic/dependency_detection.rb', line 61 def dependencies_satisfied? !executed and check_dependencies end |
#depends_on(&block) ⇒ Object
139 140 141 |
# File 'lib/new_relic/dependency_detection.rb', line 139 def depends_on(&block) @dependencies << block if block end |
#deprecated_disabled_configured? ⇒ Boolean
TODO: MAJOR VERSION will only return true if a disabled key is found and is truthy
149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/new_relic/dependency_detection.rb', line 149 def deprecated_disabled_configured? return false if self.name.nil? key = "disable_#{self.name}".to_sym return false unless ::NewRelic::Agent.config[key] == true ::NewRelic::Agent.logger.debug("Not installing #{self.name} instrumentation because of configuration #{key}") ::NewRelic::Agent.logger.debug( \ "[DEPRECATED] configuration #{key} for #{self.name} will be removed in the next major release. " \ "Use `#{config_key}` with one of `#{VALID_CONFIG_VALUES.map(&:to_s).inspect}`" ) return true end |
#execute ⇒ Object
113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/new_relic/dependency_detection.rb', line 113 def execute @executes.each do |x| begin x.call rescue => err NewRelic::Agent.logger.error("Error while installing #{self.name} instrumentation:", err) break end end ensure executed! end |
#executed! ⇒ Object
45 46 47 |
# File 'lib/new_relic/dependency_detection.rb', line 45 def executed! @executed = true end |
#executes(&block) ⇒ Object
216 217 218 |
# File 'lib/new_relic/dependency_detection.rb', line 216 def executes(&block) @executes << block if block end |
#extract_supportability_name(instrumenting_module) ⇒ Object
Extracts the instrumented library name from the instrumenting module’s name Given “NewRelic::Agent::Instrumentation::NetHTTP::Prepend” Will extract “NetHTTP” which is in the 2nd to last spot
83 84 85 |
# File 'lib/new_relic/dependency_detection.rb', line 83 def extract_supportability_name(instrumenting_module) instrumenting_module.to_s.split('::')[-2] end |
#fetch_config_value(key) ⇒ Object
fetches and transform potentially invalid value given to one of the valid config values logs the resolved value during debug mode.
187 188 189 190 191 |
# File 'lib/new_relic/dependency_detection.rb', line 187 def fetch_config_value(key) valid_value = valid_config_value(::NewRelic::Agent.config[key].to_s.to_sym) ::NewRelic::Agent.logger.debug("Using #{valid_value} configuration value for #{self.name} to configure instrumentation") return valid_value end |
#log_and_instrument(method, instrumenting_module, supportability_name) ⇒ Object
87 88 89 90 91 92 |
# File 'lib/new_relic/dependency_detection.rb', line 87 def log_and_instrument(method, instrumenting_module, supportability_name) supportability_name ||= extract_supportability_name(instrumenting_module) NewRelic::Agent.logger.info("Installing New Relic supported #{supportability_name} instrumentation using #{method}") NewRelic::Agent.record_metric("Supportability/Instrumentation/#{supportability_name}/#{method}", 0.0) yield end |
#named(new_name) ⇒ Object
208 209 210 |
# File 'lib/new_relic/dependency_detection.rb', line 208 def named(new_name) self.name = new_name end |
#prepend_conflicts? ⇒ Boolean
228 229 230 231 232 233 234 235 236 237 |
# File 'lib/new_relic/dependency_detection.rb', line 228 def prepend_conflicts? @prepend_conflicts.any? do |conflict| begin conflict.call rescue => err NewRelic::Agent.logger.error("Error while checking prepend conflicts #{self.name}:", err) false # assumes no conflicts exist since `prepend` is preferred method of instrumenting end end end |
#prepend_instrument(target_class, instrumenting_module, supportability_name = nil) ⇒ Object
94 95 96 97 98 |
# File 'lib/new_relic/dependency_detection.rb', line 94 def prepend_instrument(target_class, instrumenting_module, supportability_name = nil) log_and_instrument('Prepend', instrumenting_module, supportability_name) do target_class.send(:prepend, instrumenting_module) end end |
#source_location_for(klass, method_name) ⇒ Object
76 77 78 |
# File 'lib/new_relic/dependency_detection.rb', line 76 def source_location_for(klass, method_name) Object.instance_method(:method).bind(klass.allocate).call(method_name).source_location.to_s end |
#update_config_value(use_prepend) ⇒ Object
update any :auto config value to be either :prepend or :chain after auto determination has selected one of those to use
195 196 197 198 199 200 |
# File 'lib/new_relic/dependency_detection.rb', line 195 def update_config_value(use_prepend) if config_key && auto_configured? NewRelic::Agent.config.instance_variable_get(:@cache)[config_key] = use_prepend ? :prepend : :chain end use_prepend end |
#use_prepend? ⇒ Boolean
224 225 226 |
# File 'lib/new_relic/dependency_detection.rb', line 224 def use_prepend? update_config_value(prepend_configured? || (auto_configured? && !prepend_conflicts?)) end |
#valid_config_value(retrieved_value) ⇒ Object
returns only a valid value for instrumentation configuration If user uses “enabled” it’s converted to “auto”
181 182 183 |
# File 'lib/new_relic/dependency_detection.rb', line 181 def valid_config_value(retrieved_value) VALID_CONFIG_VALUES.include?(retrieved_value) ? retrieved_value : AUTO_CONFIG_VALUE end |